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