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