Optimised PID method
[jalview.git] / src / jalview / util / Comparison.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.util;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 \r
24 /**\r
25  * DOCUMENT ME!\r
26  *\r
27  * @author $author$\r
28  * @version $Revision$\r
29  */\r
30 public class Comparison\r
31 {\r
32   /** DOCUMENT ME!! */\r
33   public static String GapChars = " .-";\r
34 \r
35   /**\r
36    * DOCUMENT ME!\r
37    *\r
38    * @param ii DOCUMENT ME!\r
39    * @param jj DOCUMENT ME!\r
40    *\r
41    * @return DOCUMENT ME!\r
42    */\r
43   public static float compare(SequenceI ii, SequenceI jj)\r
44   {\r
45     return Comparison.compare(ii, jj, 0, ii.getLength() - 1);\r
46   }\r
47 \r
48   /**\r
49    * this was supposed to be an ungapped pid calculation\r
50    * @param ii SequenceI\r
51    * @param jj SequenceI\r
52    * @param start int\r
53    * @param end int\r
54    * @return float\r
55    */\r
56   public static float compare(SequenceI ii, SequenceI jj, int start, int end)\r
57   {\r
58     String si = ii.getSequence();\r
59     String sj = jj.getSequence();\r
60 \r
61     int ilen = si.length() - 1;\r
62     int jlen = sj.length() - 1;\r
63 \r
64     while (jalview.util.Comparison.isGap(si.charAt(start + ilen)))\r
65     {\r
66       ilen--;\r
67     }\r
68 \r
69     while (jalview.util.Comparison.isGap(sj.charAt(start + jlen)))\r
70     {\r
71       jlen--;\r
72     }\r
73 \r
74     int count = 0;\r
75     int match = 0;\r
76     float pid = -1;\r
77 \r
78     if (ilen > jlen)\r
79     {\r
80       for (int j = 0; j < jlen; j++)\r
81       {\r
82         if (si.substring(start + j, start + j + 1).equals(sj.substring(start +\r
83             j, start + j + 1)))\r
84         {\r
85           match++;\r
86         }\r
87 \r
88         count++;\r
89       }\r
90 \r
91       pid = (float) match / (float) ilen * 100;\r
92     }\r
93     else\r
94     {\r
95       for (int j = 0; j < jlen; j++)\r
96       {\r
97         if (si.substring(start + j, start + j + 1).equals(sj.substring(start +\r
98             j, start + j + 1)))\r
99         {\r
100           match++;\r
101         }\r
102 \r
103         count++;\r
104       }\r
105 \r
106       pid = (float) match / (float) jlen * 100;\r
107     }\r
108 \r
109     return pid;\r
110   }\r
111 \r
112   /**\r
113    * this is a gapped PID calculation\r
114    *\r
115    * @param s1 SequenceI\r
116    * @param s2 SequenceI\r
117    * @return float\r
118    */\r
119   public final static float PID(SequenceI seq1, SequenceI seq2)\r
120   {\r
121     return PID(seq1, seq2, 0, seq1.getLength());\r
122   }\r
123 \r
124   static final int caseShift = 'a' - 'A';\r
125 \r
126   // Another pid with region specification\r
127   public final static  float PID(SequenceI seq1, SequenceI seq2, int start, int end)\r
128   {\r
129     String s1 = seq1.getSequence();//.toUpperCase();\r
130     String s2 = seq2.getSequence();//.toUpperCase();\r
131     int s1len = s1.length();\r
132     int s2len = s2.length();\r
133 \r
134 \r
135     int len = Math.min(s1len, s2len);\r
136 \r
137     if (end < len)\r
138     {\r
139       len = end;\r
140     }\r
141 \r
142     if (len < start)\r
143     {\r
144       start = len - 1; // we just use a single residue for the difference\r
145     }\r
146 \r
147 \r
148     int bad = 0;\r
149     char chr1;\r
150     char chr2;\r
151 \r
152 \r
153     for (int i = start; i < len; i++)\r
154     {\r
155       chr1 =  s1.charAt(i) ;\r
156 \r
157       chr2 =  s2.charAt(i) ;\r
158 \r
159       if ('a' <= chr1 && chr1 <= 'z')\r
160       {\r
161         // TO UPPERCASE !!!\r
162         //Faster than toUpperCase\r
163         chr1 -= caseShift;\r
164       }\r
165       if ('a' <= chr2 && chr2 <= 'z')\r
166       {\r
167         // TO UPPERCASE !!!\r
168         //Faster than toUpperCase\r
169         chr2 -= caseShift;\r
170       }\r
171 \r
172 \r
173       if (chr1!=chr2 && !isGap(chr1) && !isGap(chr2) )\r
174       {\r
175           bad++;\r
176       }\r
177     }\r
178 \r
179     return ( (float) 100 * (len - bad)) / len;\r
180   }\r
181 \r
182   /**\r
183    * DOCUMENT ME!\r
184    *\r
185    * @param c DOCUMENT ME!\r
186    *\r
187    * @return DOCUMENT ME!\r
188    */\r
189   public static boolean isGap(char c)\r
190   {\r
191     return (c == '-' || c == '.' || c == ' ') ? true : false;\r
192   }\r
193 \r
194   public static boolean isNucleotide(SequenceI [] seqs)\r
195   {\r
196     int i = 0, iSize = seqs.length, j, jSize;\r
197     float nt = 0, aa = 0;\r
198     char c;\r
199     while (i < iSize)\r
200     {\r
201       jSize = seqs[i].getLength();\r
202       for (j = 0; j < jSize; j++)\r
203       {\r
204         c = seqs[i].getCharAt(j);\r
205         if ('a' <= c && c <= 'z')\r
206           c -= ('a' - 'A');\r
207 \r
208         if (c == 'A' || c == 'G' || c == 'C' || c == 'T' || c == 'U')\r
209           nt++;\r
210         else if (!jalview.util.Comparison.isGap( seqs[i].getCharAt(j)))\r
211         {\r
212           aa++;\r
213         }\r
214       }\r
215       i++;\r
216     }\r
217 \r
218     if ( (nt / (nt + aa)) > 0.85f)\r
219       return true;\r
220     else\r
221       return false;\r
222 \r
223   }\r
224 }\r