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