GPL license added
[jalview.git] / src / jalview / analysis / AAFrequency.java
1 /*\r
2 * Jalview - A Sequence Alignment Editor and Viewer\r
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4 *\r
5 * This program is free software; you can redistribute it and/or\r
6 * modify it under the terms of the GNU General Public License\r
7 * as published by the Free Software Foundation; either version 2\r
8 * of the License, or (at your option) any later version.\r
9 *\r
10 * This program is distributed in the hope that it will be useful,\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 * GNU General Public License for more details.\r
14 *\r
15 * You should have received a copy of the GNU General Public License\r
16 * along with this program; if not, write to the Free Software\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18 */\r
19 \r
20 package jalview.analysis;\r
21 \r
22 import jalview.jbgui.*;\r
23 import jalview.datamodel.*;\r
24 import jalview.io.*;\r
25 import jalview.analysis.*;\r
26 \r
27 import java.awt.*;\r
28 import java.applet.Applet;\r
29 import java.util.*;\r
30 import java.net.*;\r
31 import java.io.*;\r
32 \r
33 public class AAFrequency {\r
34 \r
35     // Takes in a vector of sequences and column start and column end\r
36     // and returns a vector of size (end-start+1). Each element of the\r
37     // vector contains a hashtable with the keys being residues and\r
38     // the values being the count of each residue in that column.\r
39     // This class is used extensively in calculating alignment colourschemes\r
40     // that depend on the amount of conservation in each alignment column.\r
41 \r
42 \r
43     public static Vector calculate(Vector sequences,int start,int end) {\r
44 \r
45     Vector result = new Vector();\r
46 \r
47     for (int i = start;i <= end; i++)\r
48     {\r
49 \r
50       Hashtable residueHash = new Hashtable();\r
51       int       maxCount    = 0;\r
52       String    maxResidue  = "-";\r
53       int       nongap      = 0;\r
54       for (int j=0; j < sequences.size(); j++)\r
55       {\r
56 \r
57         if (sequences.elementAt(j) instanceof Sequence)\r
58         {\r
59           Sequence s = (Sequence)sequences.elementAt(j);\r
60 \r
61           if (s.getSequence().length() > i)\r
62           {\r
63 \r
64             String res = s.getSequence().charAt(i)+"";\r
65 \r
66             if (!jalview.util.Comparison.isGap(res.charAt(0)))\r
67               nongap++;\r
68             else\r
69               res = "-"; // we always use this for gaps in the property vectors\r
70 \r
71             if (residueHash.containsKey(res))\r
72             {\r
73 \r
74               int count = ((Integer)residueHash.get(res)).intValue() ;\r
75               count++;\r
76 \r
77               if (!jalview.util.Comparison.isGap(res.charAt(0)) && count >= maxCount)\r
78               {\r
79 \r
80                   if(count>maxCount)\r
81                       maxResidue = res;\r
82                   else if(maxResidue.indexOf(res)==-1)\r
83                       maxResidue += res;\r
84 \r
85                   maxCount = count;\r
86               }\r
87 \r
88               residueHash.put(res,new Integer(count));\r
89             }\r
90             else\r
91               residueHash.put(res,new Integer(1));\r
92 \r
93 \r
94           }\r
95           else\r
96           {\r
97             if (residueHash.containsKey("-"))\r
98             {\r
99               int count = ((Integer)residueHash.get("-")).intValue() ;\r
100               count++;\r
101               residueHash.put("-",new Integer(count));\r
102             }\r
103             else\r
104               residueHash.put("-",new Integer(1));\r
105 \r
106           }\r
107         }\r
108       }\r
109 \r
110       residueHash.put("maxCount",new Integer(maxCount));\r
111       if(maxCount<0)\r
112         System.out.println("asasa "+maxCount);\r
113       residueHash.put("maxResidue", maxResidue);\r
114       residueHash.put("size", new Integer(sequences.size()));\r
115       residueHash.put("nongap", new Integer(nongap));\r
116       result.addElement(residueHash);\r
117     }\r
118 \r
119     return result;\r
120   }\r
121 \r
122     public static Vector calculatePID(SequenceI refseq,Vector sequences,int window,int start,int end) {\r
123 \r
124     Vector result = new Vector();\r
125 \r
126     boolean init = true;\r
127 \r
128 \r
129     Vector prev = null;\r
130 \r
131     for (int i = start;i <= end; i++) {\r
132         Vector values = new Vector();\r
133 \r
134         result.addElement(values);\r
135 \r
136         // If start < window/2 then set value to zero.\r
137 \r
138         if (i< window/2 || i >= refseq.getSequence().length()-window/2) {\r
139             for (int j = 0; j < sequences.size(); j++) {\r
140                 values.addElement(new Integer(0));\r
141             }\r
142         } else  if (init == true) {\r
143             init = false;\r
144 \r
145             int winstart = i-window/2;\r
146             int winend   = i+window/2;\r
147 \r
148             if (window%2 != 0) {\r
149               winend++;\r
150             }\r
151 \r
152             for (int j = 0; j < sequences.size(); j++) {\r
153                 values.addElement(new Integer(0));\r
154             }\r
155 \r
156             for (int k = winstart; k <= winend; k++) {\r
157                 String refchar = refseq.getSequence().substring(k,k+1);\r
158                 if (jalview.util.Comparison.isGap(refchar.charAt(0)))\r
159                   refchar="-";\r
160                 else {\r
161                   for (int j = 0; j < sequences.size(); j++) {\r
162 \r
163                     Sequence s = (Sequence)sequences.elementAt(j);\r
164 \r
165                     if (s.getSequence().length() > k) {\r
166 \r
167                       String res = s.getSequence().substring(k,k+1); // no gapchar test needed\r
168 \r
169                       if (res.equals(refchar)) {\r
170                         int val = ((Integer)values.elementAt(j)).intValue();\r
171                         val++;\r
172                         values.setElementAt(new Integer(val),j);\r
173                       }\r
174                     }\r
175                   }\r
176                 }\r
177 \r
178               }\r
179 \r
180             prev = values;\r
181         } else {\r
182             int winstart = i-window/2;\r
183             int winend   = i+window/2;\r
184 \r
185             if (window%2 != 0) {\r
186               winend++;\r
187             }\r
188             // We need to take the previous set of values\r
189             // subtract the pid at winstart-1\r
190             // and add the pid at winend;\r
191 \r
192             String pre_refchar  = refseq.getSequence().substring(winstart-1,winstart);\r
193             String pos_refchar = "-";\r
194 \r
195             if (refseq.getSequence().length() > winend) {\r
196               pos_refchar  = refseq.getSequence().substring(winend,winend+1);\r
197             }\r
198 \r
199             for (int j = 0; j < sequences.size(); j++) {\r
200                 // First copy the pid value from i-1\r
201 \r
202                 int val = ((Integer)prev.elementAt(j)).intValue();\r
203 \r
204                 Sequence s = (Sequence)sequences.elementAt(j);\r
205 \r
206                 String pre_char = s.getSequence().substring(winstart-1,winstart);\r
207 \r
208                 String pos_char = "-";\r
209 \r
210                 if (s.getSequence().length() > winend) {\r
211                   pos_char = s.getSequence().substring(winend,winend+1);\r
212                 }\r
213 \r
214                 // Now substract 1 if the chars at winstart-1 match\r
215 \r
216                 if (jalview.util.Comparison.isGap(pre_refchar.charAt(0)) == false\r
217                     && pre_char.equals(pre_refchar)) {\r
218                     val--;\r
219                 }\r
220 \r
221                 if (jalview.util.Comparison.isGap(pos_refchar.charAt(0)) == false\r
222                     && pos_char.equals(pos_refchar)) {\r
223                     val++;\r
224                 }\r
225 \r
226                 values.addElement(new Integer(val));\r
227 \r
228 \r
229             }\r
230             prev = values;\r
231         }\r
232     }\r
233 \r
234     return result;\r
235     }\r
236 \r
237     public static Hashtable findBlocks(Vector seqs, int start, int end,Vector exc) {\r
238 \r
239         // start and end are in real (not relative coords);\r
240 \r
241         // The coords in the hashtable that is returned are in relative coords\r
242         // i.e. start from 0\r
243 \r
244         Hashtable blocks = new Hashtable();\r
245 \r
246         boolean prev = false;\r
247         int     bstart = -1;\r
248 \r
249         for (int i = start; i <= end ; i++) {\r
250             SequenceI seq = (SequenceI)seqs.elementAt(0);\r
251 \r
252             char      c   = seq.getCharAt(i);\r
253 \r
254             boolean found = true;\r
255 \r
256             int j = 1;\r
257 \r
258             while (j < seqs.size() && found == true) {\r
259 \r
260                 SequenceI jseq  = (SequenceI)seqs.elementAt(j);\r
261 \r
262                 if (!exc.contains(jseq)) {\r
263 \r
264                     char cc = jseq.getCharAt(i);\r
265 \r
266                     if ( cc != c) {\r
267                         found = false;\r
268                     }\r
269                 }\r
270                 j++;\r
271             }\r
272 \r
273 \r
274             if (prev == false && found == true) {\r
275                 bstart = i;\r
276             } else if (prev == true && found == false && bstart != -1) {\r
277 \r
278                 int blockstart = bstart-start;\r
279                 int blocklen   = i-bstart;\r
280 \r
281                 //System.out.println("Start len " + blockstart + " " + blocklen);\r
282 \r
283                 for (int jj = blockstart; jj < blockstart + blocklen;jj++) {\r
284                     blocks.put(new Integer(jj),new Integer(blocklen));\r
285                 }\r
286 \r
287                 bstart = -1;\r
288             }\r
289             prev = found;\r
290         }\r
291 \r
292         if (bstart != -1) {\r
293 \r
294             int blockstart = bstart-start;\r
295             int blocklen   = end-bstart;\r
296 \r
297           //  System.out.println("Start len " + blockstart + " " + blocklen);\r
298 \r
299             for (int jj = blockstart; jj < blockstart + blocklen;jj++) {\r
300                 blocks.put(new Integer(blockstart),new Integer(blocklen));\r
301             }\r
302 \r
303         }\r
304         return blocks;\r
305     }\r
306 \r
307 \r
308 \r
309     public static Hashtable findKmerCount(SequenceI seq, int start, int end,int window, int step,Vector kmers) {\r
310 \r
311        int tmpstart = start;\r
312        Hashtable vals = new Hashtable();\r
313 \r
314        while (tmpstart <= end) {\r
315 \r
316            String tmpstr = seq.getSequence().substring(tmpstart-window/2,tmpstart+window/2);\r
317 \r
318            int count = 0;\r
319 \r
320            //System.out.println("Str " + tmpstr);\r
321 \r
322            for (int ii = 0; ii < kmers.size(); ii++) {\r
323                String kmer = ((SequenceI)kmers.elementAt(ii)).getSequence();\r
324 \r
325                int i = -1;\r
326 \r
327                while (tmpstr.indexOf(kmer,i) != -1) {\r
328                i = tmpstr.indexOf(kmer,i);\r
329 \r
330                i++;\r
331                count++;\r
332                }\r
333                ii++;\r
334            }\r
335            vals.put(new Integer(tmpstart),new Integer(count));\r
336            tmpstart += step;\r
337        }\r
338        return vals;\r
339     }\r
340 \r
341     public static Hashtable findBlockStarts(Vector seqs, int start, int end,Vector exc) {\r
342 \r
343         // start and end are in real (not relative coords);\r
344 \r
345         // The coords in the hashtable that is returned are in relative coords\r
346         // i.e. start from 0\r
347 \r
348         Hashtable blocks = new Hashtable();\r
349 \r
350         boolean prev = false;\r
351         int     bstart = -1;\r
352 \r
353         for (int i = start; i <= end ; i++) {\r
354             SequenceI seq = (SequenceI)seqs.elementAt(0);\r
355 \r
356             char      c   = seq.getCharAt(i);\r
357 \r
358             boolean found = true;\r
359 \r
360             int j = 1;\r
361 \r
362             while (j < seqs.size() && found == true) {\r
363 \r
364                 SequenceI jseq  = (SequenceI)seqs.elementAt(j);\r
365 \r
366                 if (!exc.contains(jseq)) {\r
367 \r
368                     char cc = jseq.getCharAt(i);\r
369 \r
370                     if ( cc != c) {\r
371                         found = false;\r
372                     }\r
373                 }\r
374                 j++;\r
375             }\r
376 \r
377 \r
378             if (prev == false && found == true) {\r
379                 bstart = i;\r
380             } else if (prev == true && found == false && bstart != -1) {\r
381 \r
382                 int blockstart = bstart-start;\r
383                 int blocklen   = i-bstart;\r
384 \r
385                 //              System.out.println("Start len " + blockstart + " " + blocklen);\r
386 \r
387                 //for (int jj = blockstart; jj < blockstart + blocklen;jj++) {\r
388                     blocks.put(new Integer(blockstart),new Integer(blocklen));\r
389         //      }\r
390 \r
391                 bstart = -1;\r
392             }\r
393             prev = found;\r
394         }\r
395 \r
396         if (bstart != -1) {\r
397 \r
398             int blockstart = bstart-start;\r
399             int blocklen   = end-bstart;\r
400 \r
401           //  System.out.println("Start len " + blockstart + " " + blocklen);\r
402 \r
403             //for (int jj = blockstart; jj < blockstart + blocklen;jj++) {\r
404                 blocks.put(new Integer(blockstart),new Integer(blocklen));\r
405            // }\r
406 \r
407         }\r
408         return blocks;\r
409     }\r
410 \r
411 }\r
412 \r