Id parsing moved to Sequence
[jalview.git] / src / jalview / datamodel / Sequence.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.datamodel;\r
20 \r
21 import java.awt.*;\r
22 \r
23 import java.util.*;\r
24 \r
25 \r
26 /**\r
27  * DOCUMENT ME!\r
28  *\r
29  * @author $author$\r
30  * @version $Revision$\r
31  */\r
32 public class Sequence implements SequenceI\r
33 {\r
34     SequenceI datasetSequence;\r
35     String name;\r
36     String shortName;\r
37     String sequence;\r
38     String description;\r
39     int start;\r
40     int end;\r
41     Color color = Color.white;\r
42     String pdbId;\r
43     String vamsasId;\r
44     Vector dbrefs;\r
45 \r
46 \r
47     /** DOCUMENT ME!! */\r
48     public Vector sequenceFeatures = new Vector();\r
49 \r
50     /**\r
51      * Creates a new Sequence object.\r
52      *\r
53      * @param name DOCUMENT ME!\r
54      * @param sequence DOCUMENT ME!\r
55      * @param start DOCUMENT ME!\r
56      * @param end DOCUMENT ME!\r
57      */\r
58     public Sequence(String name, String sequence, int start, int end)\r
59     {\r
60       this.name = name;\r
61       parseId();\r
62 \r
63       this.sequence = sequence;\r
64       this.start = start;\r
65       this.end = end;\r
66 \r
67       checkValidRange();\r
68     }\r
69 \r
70     void parseId()\r
71     {\r
72         // Read in any DB refs first\r
73          StringTokenizer st = new StringTokenizer(name, "|");\r
74          if(st.countTokens()<1)\r
75          {\r
76            shortName = name;\r
77            return;\r
78          }\r
79 \r
80          while (st.countTokens() > 1)\r
81          {\r
82            String a = st.nextToken();\r
83            String b = st.nextToken();\r
84            addDBRef(new DBRefEntry(a, "0", b));\r
85          }\r
86 \r
87          if (st.hasMoreTokens())\r
88            shortName = st.nextToken();\r
89 \r
90          // Remove /start-end from sequence\r
91          if (shortName.indexOf("/") > 0)\r
92          {\r
93            st = new StringTokenizer(shortName, "/");\r
94            String limits = null;\r
95            try\r
96            {\r
97              if (st.countTokens() == 2)\r
98              {\r
99                shortName = st.nextToken();\r
100 \r
101                limits = st.nextToken();\r
102 \r
103                st = new StringTokenizer(limits, "-");\r
104 \r
105                if (st.countTokens() == 2)\r
106                {\r
107                  setStart(Integer.valueOf(st.nextToken()).intValue());\r
108                  setEnd(Integer.valueOf(st.nextToken()).intValue());\r
109                }\r
110              }\r
111            }\r
112            catch (NumberFormatException ex)\r
113            {\r
114              // Problem parsing sequence limits. Just add it back to the\r
115              // Id so we dont lose this info\r
116              shortName += "/" + limits;\r
117            }\r
118          }\r
119     }\r
120 \r
121     void checkValidRange()\r
122     {\r
123       if (end < 1)\r
124       {\r
125         int endRes = 0;\r
126         char ch;\r
127         for (int j = 0; j < sequence.length(); j++)\r
128         {\r
129           ch = sequence.charAt(j);\r
130           if (!jalview.util.Comparison.isGap( (ch)))\r
131           {\r
132             endRes++;\r
133           }\r
134         }\r
135         if (endRes > 0)\r
136         {\r
137           endRes += start - 1;\r
138         }\r
139 \r
140         this.end = endRes;\r
141       }\r
142 \r
143     }\r
144 \r
145     /**\r
146      * Creates a new Sequence object.\r
147      *\r
148      * @param name DOCUMENT ME!\r
149      * @param sequence DOCUMENT ME!\r
150      */\r
151     public Sequence(String name, String sequence)\r
152     {\r
153         this(name, sequence, 1, -1);\r
154     }\r
155 \r
156     /**\r
157      * Creates a new Sequence object.\r
158      *\r
159      * @param seq DOCUMENT ME!\r
160      */\r
161     public Sequence(SequenceI seq)\r
162     {\r
163         this(seq.getName(), seq.getSequence(), seq.getStart(), seq.getEnd());\r
164     }\r
165 \r
166     /**\r
167      * DOCUMENT ME!\r
168      *\r
169      * @param v DOCUMENT ME!\r
170      */\r
171     public void setSequenceFeatures(Vector v)\r
172     {\r
173         sequenceFeatures = v;\r
174     }\r
175 \r
176     public void addSequenceFeature(SequenceFeature sf)\r
177     {\r
178       if(sequenceFeatures==null)\r
179         sequenceFeatures = new Vector();\r
180 \r
181       sequenceFeatures.addElement(sf);\r
182     }\r
183 \r
184     /**\r
185      * DOCUMENT ME!\r
186      *\r
187      * @return DOCUMENT ME!\r
188      */\r
189     public Vector getSequenceFeatures()\r
190     {\r
191         return sequenceFeatures;\r
192     }\r
193 \r
194     /**\r
195      * DOCUMENT ME!\r
196      *\r
197      * @param id DOCUMENT ME!\r
198      */\r
199     public void setPDBId(String id)\r
200     {\r
201         pdbId = id;\r
202     }\r
203 \r
204     /**\r
205      * DOCUMENT ME!\r
206      *\r
207      * @return DOCUMENT ME!\r
208      */\r
209     public String getPDBId()\r
210     {\r
211         return pdbId;\r
212     }\r
213 \r
214     /**\r
215      * DOCUMENT ME!\r
216      *\r
217      * @return DOCUMENT ME!\r
218      */\r
219     public String getDisplayId(boolean dbref, boolean jvsuffix)\r
220     {\r
221       StringBuffer result = new StringBuffer();\r
222       if (dbref && dbrefs != null)\r
223       {\r
224         for (int i = 0; i < dbrefs.size(); i++)\r
225         {\r
226           DBRefEntry entry = (DBRefEntry) dbrefs.elementAt(i);\r
227           result.append(entry.getSource() + "|" + entry.getAccessionId() + "|");\r
228         }\r
229       }\r
230 \r
231       result.append(shortName);\r
232 \r
233       if (jvsuffix)\r
234       {\r
235         result.append("/" + start + "-" + end);\r
236       }\r
237 \r
238       return result.toString();\r
239     }\r
240 \r
241     /**\r
242      * DOCUMENT ME!\r
243      *\r
244      * @param name DOCUMENT ME!\r
245      */\r
246     public void setName(String name)\r
247     {\r
248       this.name = name;\r
249       this.parseId();\r
250     }\r
251 \r
252     /**\r
253      * DOCUMENT ME!\r
254      *\r
255      * @return DOCUMENT ME!\r
256      */\r
257     public String getName()\r
258     {\r
259        return this.name;\r
260     }\r
261 \r
262     /**\r
263      * DOCUMENT ME!\r
264      *\r
265      * @param start DOCUMENT ME!\r
266      */\r
267     public void setStart(int start)\r
268     {\r
269         this.start = start;\r
270     }\r
271 \r
272     /**\r
273      * DOCUMENT ME!\r
274      *\r
275      * @return DOCUMENT ME!\r
276      */\r
277     public int getStart()\r
278     {\r
279         return this.start;\r
280     }\r
281 \r
282     /**\r
283      * DOCUMENT ME!\r
284      *\r
285      * @param end DOCUMENT ME!\r
286      */\r
287     public void setEnd(int end)\r
288     {\r
289         this.end = end;\r
290     }\r
291 \r
292     /**\r
293      * DOCUMENT ME!\r
294      *\r
295      * @return DOCUMENT ME!\r
296      */\r
297     public int getEnd()\r
298     {\r
299         return this.end;\r
300     }\r
301 \r
302     /**\r
303      * DOCUMENT ME!\r
304      *\r
305      * @return DOCUMENT ME!\r
306      */\r
307     public int getLength()\r
308     {\r
309         return this.sequence.length();\r
310     }\r
311 \r
312     /**\r
313      * DOCUMENT ME!\r
314      *\r
315      * @param seq DOCUMENT ME!\r
316      */\r
317     public void setSequence(String seq)\r
318     {\r
319         this.sequence = seq;\r
320         checkValidRange();\r
321     }\r
322 \r
323     /**\r
324      * DOCUMENT ME!\r
325      *\r
326      * @return DOCUMENT ME!\r
327      */\r
328     public String getSequence()\r
329     {\r
330         return this.sequence;\r
331     }\r
332 \r
333     /**\r
334      * DOCUMENT ME!\r
335      *\r
336      * @param start DOCUMENT ME!\r
337      * @param end DOCUMENT ME!\r
338      *\r
339      * @return DOCUMENT ME!\r
340      */\r
341     public String getSequence(int start, int end)\r
342     {\r
343         // JBPNote - left to user to pad the result here (TODO:Decide on this policy)\r
344         if (start >= sequence.length())\r
345         {\r
346             return "";\r
347         }\r
348 \r
349         if (end >= sequence.length())\r
350         {\r
351             end = sequence.length();\r
352         }\r
353 \r
354         return this.sequence.substring(start, end);\r
355     }\r
356 \r
357     /**\r
358      * DOCUMENT ME!\r
359      *\r
360      * @param i DOCUMENT ME!\r
361      *\r
362      * @return DOCUMENT ME!\r
363      */\r
364     public char getCharAt(int i)\r
365     {\r
366         if (i < sequence.length())\r
367         {\r
368             return sequence.charAt(i);\r
369         }\r
370         else\r
371         {\r
372             return ' ';\r
373         }\r
374     }\r
375 \r
376     /**\r
377      * DOCUMENT ME!\r
378      *\r
379      * @param desc DOCUMENT ME!\r
380      */\r
381     public void setDescription(String desc)\r
382     {\r
383         this.description = desc;\r
384     }\r
385 \r
386     /**\r
387      * DOCUMENT ME!\r
388      *\r
389      * @return DOCUMENT ME!\r
390      */\r
391     public String getDescription()\r
392     {\r
393         return this.description;\r
394     }\r
395 \r
396     /**\r
397      * DOCUMENT ME!\r
398      *\r
399      * @param pos DOCUMENT ME!\r
400      *\r
401      * @return DOCUMENT ME!\r
402      */\r
403     public int findIndex(int pos)\r
404     {\r
405         // returns the alignment position for a residue\r
406         int j = start;\r
407         int i = 0;\r
408 \r
409         while ((i < sequence.length()) && (j <= end) && (j <= pos))\r
410         {\r
411             char c = sequence.charAt(i);\r
412 \r
413             if (!jalview.util.Comparison.isGap((c)))\r
414             {\r
415                 j++;\r
416             }\r
417 \r
418             i++;\r
419         }\r
420 \r
421         if ((j == end) && (j < pos))\r
422         {\r
423             return end + 1;\r
424         }\r
425         else\r
426         {\r
427             return i;\r
428         }\r
429     }\r
430 \r
431     /**\r
432      * DOCUMENT ME!\r
433      *\r
434      * @param i DOCUMENT ME!\r
435      *\r
436      * @return DOCUMENT ME!\r
437      */\r
438     public int findPosition(int i)\r
439     {\r
440         // Returns the sequence position for an alignment position\r
441         int j = 0;\r
442         int pos = start;\r
443 \r
444         while ((j < i) && (j < sequence.length()))\r
445         {\r
446             char c = sequence.charAt(j);\r
447 \r
448             if (!jalview.util.Comparison.isGap((c)))\r
449             {\r
450                 pos++;\r
451             }\r
452 \r
453             j++;\r
454         }\r
455 \r
456         return pos;\r
457     }\r
458 \r
459     /**\r
460      * DOCUMENT ME!\r
461      *\r
462      * @return DOCUMENT ME!\r
463      */\r
464     public int[] gapMap()\r
465     {\r
466         // Returns an int array giving the position of each residue in the sequence in the alignment\r
467         String seq = jalview.analysis.AlignSeq.extractGaps("-. ", sequence);\r
468         int[] map = new int[seq.length()];\r
469         int j = 0;\r
470         int p = 0;\r
471 \r
472         while (j < sequence.length())\r
473         {\r
474             if (!jalview.util.Comparison.isGap(sequence.charAt(j)))\r
475             {\r
476                 map[p++] = j;\r
477             }\r
478 \r
479             j++;\r
480         }\r
481 \r
482         return map;\r
483     }\r
484 \r
485     /**\r
486      * DOCUMENT ME!\r
487      *\r
488      * @param i DOCUMENT ME!\r
489      */\r
490     public void deleteCharAt(int i)\r
491     {\r
492         if (i >= sequence.length())\r
493         {\r
494             return;\r
495         }\r
496 \r
497         sequence = sequence.substring(0, i) + sequence.substring(i + 1);\r
498     }\r
499 \r
500     /**\r
501      * DOCUMENT ME!\r
502      *\r
503      * @param i DOCUMENT ME!\r
504      * @param j DOCUMENT ME!\r
505      */\r
506     public void deleteChars(int i, int j)\r
507     {\r
508         if (i >= sequence.length())\r
509         {\r
510             return;\r
511         }\r
512 \r
513         if (j >= sequence.length())\r
514         {\r
515             sequence = sequence.substring(0, i);\r
516         }\r
517         else\r
518         {\r
519             sequence = sequence.substring(0, i) + sequence.substring(j);\r
520         }\r
521     }\r
522 \r
523     /**\r
524      * DOCUMENT ME!\r
525      *\r
526      * @param i DOCUMENT ME!\r
527      * @param c DOCUMENT ME!\r
528      */\r
529     public void insertCharAt(int i, char c)\r
530     {\r
531         insertCharAt(i, c, true);\r
532     }\r
533 \r
534     /**\r
535      * DOCUMENT ME!\r
536      *\r
537      * @param i DOCUMENT ME!\r
538      * @param c DOCUMENT ME!\r
539      * @param chop DOCUMENT ME!\r
540      */\r
541     public void insertCharAt(int i, char c, boolean chop)\r
542     {\r
543         String tmp = new String(sequence);\r
544 \r
545         if (i < sequence.length())\r
546         {\r
547             sequence = tmp.substring(0, i) + String.valueOf(c) +\r
548                 tmp.substring(i);\r
549         }\r
550         else\r
551         {\r
552             // JBPNote : padding char at end of sequence. We'll not get away with this when we insert residues, I bet!\r
553             char[] ch = new char[(1 + i) - sequence.length()];\r
554 \r
555             for (int j = 0, k = ch.length; j < k; j++)\r
556                 ch[j] = c;\r
557 \r
558             sequence = tmp + String.valueOf(ch);\r
559         }\r
560     }\r
561 \r
562     /**\r
563      * DOCUMENT ME!\r
564      *\r
565      * @param c DOCUMENT ME!\r
566      */\r
567     public void setColor(Color c)\r
568     {\r
569         this.color = c;\r
570     }\r
571 \r
572     /**\r
573      * DOCUMENT ME!\r
574      *\r
575      * @return DOCUMENT ME!\r
576      */\r
577     public Color getColor()\r
578     {\r
579         return color;\r
580     }\r
581 \r
582     public String getVamsasId()\r
583     {\r
584       return vamsasId;\r
585     }\r
586 \r
587     public void setVamsasId(String id)\r
588     {\r
589       vamsasId = id;\r
590     }\r
591 \r
592     public void setDBRef(Vector dbref)\r
593     {\r
594       dbrefs = dbref;\r
595     }\r
596     public Vector getDBRef()\r
597     {\r
598       return dbrefs;\r
599     }\r
600 \r
601     public void addDBRef(DBRefEntry entry)\r
602     {\r
603       if(dbrefs == null)\r
604         dbrefs = new Vector();\r
605 \r
606       dbrefs.addElement(entry);\r
607     }\r
608 \r
609     public void setDatasetSequence(SequenceI seq)\r
610     {\r
611       datasetSequence = seq;\r
612     }\r
613 \r
614     public SequenceI getDatasetSequence()\r
615     {\r
616       return datasetSequence;\r
617     }\r
618 \r
619 }\r