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