Convenient function findEndRes
[jalview.git] / src / jalview / datamodel / SequenceGroup.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2006 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 jalview.analysis.*;\r
22 \r
23 import jalview.schemes.*;\r
24 \r
25 import java.awt.*;\r
26 \r
27 import java.util.*;\r
28 \r
29 \r
30 /**\r
31  * DOCUMENT ME!\r
32  *\r
33  * @author $author$\r
34  * @version $Revision$\r
35  */\r
36 public class SequenceGroup\r
37 {\r
38     String groupName;\r
39     Conservation conserve;\r
40     Vector aaFrequency;\r
41     boolean displayBoxes;\r
42     boolean displayText;\r
43     boolean colourText;\r
44     private Vector sequences = new Vector();\r
45     int width = -1;\r
46 \r
47     /** DOCUMENT ME!! */\r
48     public ColourSchemeI cs;\r
49     int startRes = 0;\r
50     int endRes = 0;\r
51     Color outlineColour = Color.black;\r
52 \r
53     /**\r
54      * Creates a new SequenceGroup object.\r
55      */\r
56     public SequenceGroup()\r
57     {\r
58         groupName = "Group";\r
59         this.displayBoxes = true;\r
60         this.displayText = true;\r
61         this.colourText = false;\r
62         cs = null;\r
63     }\r
64 \r
65     /**\r
66      * Creates a new SequenceGroup object.\r
67      *\r
68      * @param sequences DOCUMENT ME!\r
69      * @param groupName DOCUMENT ME!\r
70      * @param scheme DOCUMENT ME!\r
71      * @param displayBoxes DOCUMENT ME!\r
72      * @param displayText DOCUMENT ME!\r
73      * @param colourText DOCUMENT ME!\r
74      * @param start DOCUMENT ME!\r
75      * @param end DOCUMENT ME!\r
76      */\r
77     public SequenceGroup(Vector sequences, String groupName,\r
78         ColourSchemeI scheme, boolean displayBoxes, boolean displayText,\r
79         boolean colourText, int start, int end)\r
80     {\r
81         this.sequences = sequences;\r
82         this.groupName = groupName;\r
83         this.displayBoxes = displayBoxes;\r
84         this.displayText = displayText;\r
85         this.colourText = colourText;\r
86         this.cs = scheme;\r
87         startRes = start;\r
88         endRes = end;\r
89         recalcConservation();\r
90     }\r
91 \r
92     /**\r
93      * Creates a new SequenceGroup object.\r
94      *\r
95      * @param groupName DOCUMENT ME!\r
96      * @param scheme DOCUMENT ME!\r
97      * @param displayBoxes DOCUMENT ME!\r
98      * @param displayText DOCUMENT ME!\r
99      * @param colourText DOCUMENT ME!\r
100      * @param start DOCUMENT ME!\r
101      * @param end DOCUMENT ME!\r
102      */\r
103     public SequenceGroup(String groupName, ColourSchemeI scheme,\r
104         boolean displayBoxes, boolean displayText, boolean colourText,\r
105         int start, int end)\r
106     {\r
107         this.groupName = groupName;\r
108         this.displayBoxes = displayBoxes;\r
109         this.displayText = displayText;\r
110         this.colourText = colourText;\r
111         this.cs = scheme;\r
112         startRes = start;\r
113         endRes = end;\r
114     }\r
115 \r
116     public SequenceI [] getSelectionAsNewSequences(AlignmentI align)\r
117     {\r
118       int iSize = sequences.size();\r
119       SequenceI [] seqs = new SequenceI[iSize];\r
120       SequenceI [] inorder = getSequencesInOrder(align);\r
121 \r
122     for (int i = 0; i < iSize; i++)\r
123     {\r
124       SequenceI seq = inorder[i];\r
125 \r
126       seqs[i] = new Sequence(seq.getName(),\r
127                              seq.getSequence(startRes, endRes + 1),\r
128                              seq.findPosition(startRes),\r
129                              findEndRes(seq));\r
130 \r
131       seqs[i].setDescription(seq.getDescription());\r
132       seqs[i].setDBRef(seq.getDBRef());\r
133       seqs[i].setSequenceFeatures(seq.getSequenceFeatures());\r
134       if (seq.getDatasetSequence() != null)\r
135         seqs[i].setDatasetSequence(seq.getDatasetSequence());\r
136 \r
137       if(seq.getAnnotation()!=null)\r
138       {\r
139         for(int a=0; a<seq.getAnnotation().length; a++)\r
140           seqs[i].addAlignmentAnnotation(seq.getAnnotation()[a]);\r
141       }\r
142     }\r
143 \r
144     return seqs;\r
145 \r
146     }\r
147 \r
148     /**\r
149      * If sequence ends in gaps, the end residue can\r
150      * be correctly calculated here\r
151      * @param seq SequenceI\r
152      * @return int\r
153      */\r
154     public int findEndRes(SequenceI seq)\r
155     {\r
156       int eres = 0;\r
157       char ch;\r
158 \r
159       for (int j = 0; j < endRes + 1 && j < seq.getLength(); j++)\r
160       {\r
161         ch = seq.getCharAt(j);\r
162         if (!jalview.util.Comparison.isGap( (ch)))\r
163         {\r
164           eres++;\r
165         }\r
166       }\r
167 \r
168       if (eres > 0)\r
169       {\r
170         eres += seq.getStart() - 1;\r
171       }\r
172 \r
173       return eres;\r
174     }\r
175 \r
176     public Vector getSequences(boolean includeHidden)\r
177     {\r
178       if(!includeHidden)\r
179         return sequences;\r
180       else\r
181       {\r
182         Vector allSequences = new Vector();\r
183         SequenceI seq;\r
184         for (int i = 0; i < sequences.size(); i++)\r
185         {\r
186           seq = (SequenceI) sequences.elementAt(i);\r
187           allSequences.addElement(seq);\r
188           if (seq.getHiddenSequences() != null)\r
189           {\r
190             for (int h = 0; h < seq.getHiddenSequences().getSize(false); h++)\r
191             {\r
192               allSequences.addElement(\r
193                   seq.getHiddenSequences().getSequenceAt(h)\r
194                   );\r
195             }\r
196           }\r
197         }\r
198 \r
199         return allSequences;\r
200       }\r
201     }\r
202 \r
203     /**\r
204      * DOCUMENT ME!\r
205      *\r
206      * @param col DOCUMENT ME!\r
207      *\r
208      * @return DOCUMENT ME!\r
209      */\r
210     public boolean adjustForRemoveLeft(int col)\r
211     {\r
212         // return value is true if the group still exists\r
213         if (startRes >= col)\r
214         {\r
215             startRes = startRes - col;\r
216         }\r
217 \r
218         if (endRes >= col)\r
219         {\r
220             endRes = endRes - col;\r
221 \r
222             if (startRes > endRes)\r
223             {\r
224                 startRes = 0;\r
225             }\r
226         }\r
227         else\r
228         {\r
229             // must delete this group!!\r
230             return false;\r
231         }\r
232 \r
233         return true;\r
234     }\r
235 \r
236     /**\r
237      * DOCUMENT ME!\r
238      *\r
239      * @param col DOCUMENT ME!\r
240      *\r
241      * @return DOCUMENT ME!\r
242      */\r
243     public boolean adjustForRemoveRight(int col)\r
244     {\r
245         if (startRes > col)\r
246         {\r
247             // delete this group\r
248             return false;\r
249         }\r
250 \r
251         if (endRes >= col)\r
252         {\r
253             endRes = col;\r
254         }\r
255 \r
256         return true;\r
257     }\r
258 \r
259     /**\r
260      * DOCUMENT ME!\r
261      *\r
262      * @return DOCUMENT ME!\r
263      */\r
264     public String getName()\r
265     {\r
266         return groupName;\r
267     }\r
268 \r
269     /**\r
270      * DOCUMENT ME!\r
271      *\r
272      * @param name DOCUMENT ME!\r
273      */\r
274     public void setName(String name)\r
275     {\r
276         groupName = name;\r
277     }\r
278 \r
279     /**\r
280      * DOCUMENT ME!\r
281      *\r
282      * @return DOCUMENT ME!\r
283      */\r
284     public Conservation getConservation()\r
285     {\r
286         return conserve;\r
287     }\r
288 \r
289     /**\r
290      * DOCUMENT ME!\r
291      *\r
292      * @param c DOCUMENT ME!\r
293      */\r
294     public void setConservation(Conservation c)\r
295     {\r
296         conserve = c;\r
297     }\r
298 \r
299     /**\r
300      * DOCUMENT ME!\r
301      *\r
302      * @param s DOCUMENT ME!\r
303      * @param recalc DOCUMENT ME!\r
304      */\r
305     public void addSequence(SequenceI s, boolean recalc)\r
306     {\r
307         if (!sequences.contains(s))\r
308         {\r
309             sequences.addElement(s);\r
310         }\r
311 \r
312         if (recalc)\r
313         {\r
314             recalcConservation();\r
315         }\r
316     }\r
317 \r
318     /**\r
319      * DOCUMENT ME!\r
320      */\r
321     public void recalcConservation()\r
322     {\r
323         if(cs == null)\r
324           return;\r
325 \r
326         try\r
327         {\r
328           cs.setConsensus(AAFrequency.calculate(sequences, 0, getWidth()));\r
329 \r
330           if (cs instanceof ClustalxColourScheme)\r
331           {\r
332             ( (ClustalxColourScheme) cs).resetClustalX(sequences, getWidth());\r
333           }\r
334 \r
335           if (cs.conservationApplied())\r
336           {\r
337             Conservation c = new Conservation(groupName,\r
338                                               ResidueProperties.propHash, 3, sequences,\r
339                                               0, getWidth());\r
340             c.calculate();\r
341             c.verdict(false, 25);\r
342 \r
343             cs.setConservation(c);\r
344 \r
345             if (cs instanceof ClustalxColourScheme)\r
346             {\r
347               ( (ClustalxColourScheme) cs).resetClustalX(sequences,\r
348                                                          getWidth());\r
349             }\r
350           }\r
351         }\r
352         catch (java.lang.OutOfMemoryError err)\r
353         {\r
354           System.out.println("Out of memory loading groups: " + err);\r
355         }\r
356 \r
357     }\r
358 \r
359     /**\r
360      * DOCUMENT ME!\r
361      *\r
362      * @param s DOCUMENT ME!\r
363      * @param recalc DOCUMENT ME!\r
364      */\r
365     public void addOrRemove(SequenceI s, boolean recalc)\r
366     {\r
367         if (sequences.contains(s))\r
368         {\r
369             deleteSequence(s, recalc);\r
370         }\r
371         else\r
372         {\r
373             addSequence(s, recalc);\r
374         }\r
375     }\r
376 \r
377     /**\r
378      * DOCUMENT ME!\r
379      *\r
380      * @param s DOCUMENT ME!\r
381      * @param recalc DOCUMENT ME!\r
382      */\r
383     public void deleteSequence(SequenceI s, boolean recalc)\r
384     {\r
385         sequences.removeElement(s);\r
386 \r
387         if (recalc)\r
388         {\r
389             recalcConservation();\r
390         }\r
391     }\r
392 \r
393     /**\r
394      * DOCUMENT ME!\r
395      *\r
396      * @return DOCUMENT ME!\r
397      */\r
398     public int getStartRes()\r
399     {\r
400         return startRes;\r
401     }\r
402 \r
403     /**\r
404      * DOCUMENT ME!\r
405      *\r
406      * @return DOCUMENT ME!\r
407      */\r
408     public int getEndRes()\r
409     {\r
410         return endRes;\r
411     }\r
412 \r
413     /**\r
414      * DOCUMENT ME!\r
415      *\r
416      * @param i DOCUMENT ME!\r
417      */\r
418     public void setStartRes(int i)\r
419     {\r
420         startRes = i;\r
421     }\r
422 \r
423     /**\r
424      * DOCUMENT ME!\r
425      *\r
426      * @param i DOCUMENT ME!\r
427      */\r
428     public void setEndRes(int i)\r
429     {\r
430         endRes = i;\r
431     }\r
432 \r
433     /**\r
434      * DOCUMENT ME!\r
435      *\r
436      * @return DOCUMENT ME!\r
437      */\r
438     public int getSize(boolean includeHidden)\r
439     {\r
440       if(!includeHidden)\r
441         return sequences.size();\r
442       else\r
443       {\r
444         int total = sequences.size();\r
445         SequenceI seq;\r
446         for (int i = 0; i < sequences.size(); i++)\r
447         {\r
448           seq = (SequenceI) sequences.elementAt(i);\r
449           if (seq.getHiddenSequences() != null)\r
450           {\r
451             total += seq.getHiddenSequences().getSize(false);\r
452           }\r
453         }\r
454         return total;\r
455       }\r
456     }\r
457 \r
458     /**\r
459      * DOCUMENT ME!\r
460      *\r
461      * @param i DOCUMENT ME!\r
462      *\r
463      * @return DOCUMENT ME!\r
464      */\r
465     public SequenceI getSequenceAt(int i)\r
466     {\r
467         return (SequenceI) sequences.elementAt(i);\r
468     }\r
469 \r
470     /**\r
471      * DOCUMENT ME!\r
472      *\r
473      * @param state DOCUMENT ME!\r
474      */\r
475     public void setColourText(boolean state)\r
476     {\r
477         colourText = state;\r
478     }\r
479 \r
480     /**\r
481      * DOCUMENT ME!\r
482      *\r
483      * @return DOCUMENT ME!\r
484      */\r
485     public boolean getColourText()\r
486     {\r
487         return colourText;\r
488     }\r
489 \r
490     /**\r
491      * DOCUMENT ME!\r
492      *\r
493      * @param state DOCUMENT ME!\r
494      */\r
495     public void setDisplayText(boolean state)\r
496     {\r
497         displayText = state;\r
498     }\r
499 \r
500     /**\r
501      * DOCUMENT ME!\r
502      *\r
503      * @return DOCUMENT ME!\r
504      */\r
505     public boolean getDisplayText()\r
506     {\r
507         return displayText;\r
508     }\r
509 \r
510     /**\r
511      * DOCUMENT ME!\r
512      *\r
513      * @param state DOCUMENT ME!\r
514      */\r
515     public void setDisplayBoxes(boolean state)\r
516     {\r
517         displayBoxes = state;\r
518     }\r
519 \r
520     /**\r
521      * DOCUMENT ME!\r
522      *\r
523      * @return DOCUMENT ME!\r
524      */\r
525     public boolean getDisplayBoxes()\r
526     {\r
527         return displayBoxes;\r
528     }\r
529 \r
530     /**\r
531      * DOCUMENT ME!\r
532      *\r
533      * @return DOCUMENT ME!\r
534      */\r
535     public int getWidth()\r
536     {\r
537         // MC This needs to get reset when characters are inserted and deleted\r
538         if (sequences.size() > 0)\r
539         {\r
540             width = ((SequenceI) sequences.elementAt(0)).getLength();\r
541         }\r
542 \r
543         for (int i = 1; i < sequences.size(); i++)\r
544         {\r
545             SequenceI seq = (SequenceI) sequences.elementAt(i);\r
546 \r
547             if (seq.getLength() > width)\r
548             {\r
549                 width = seq.getLength();\r
550             }\r
551         }\r
552 \r
553         return width;\r
554     }\r
555 \r
556     /**\r
557      * DOCUMENT ME!\r
558      *\r
559      * @param c DOCUMENT ME!\r
560      */\r
561     public void setOutlineColour(Color c)\r
562     {\r
563         outlineColour = c;\r
564     }\r
565 \r
566     /**\r
567      * DOCUMENT ME!\r
568      *\r
569      * @return DOCUMENT ME!\r
570      */\r
571     public Color getOutlineColour()\r
572     {\r
573         return outlineColour;\r
574     }\r
575 \r
576     /**\r
577      *\r
578      * returns the sequences in the group ordered by the ordering given by al\r
579      *\r
580      * @param al Alignment\r
581      * @return SequenceI[]\r
582      */\r
583     public SequenceI[] getSequencesInOrder(AlignmentI al)\r
584     {\r
585         int sSize = sequences.size();\r
586         int alHeight = al.getHeight();\r
587 \r
588         SequenceI[] seqs = new SequenceI[sSize];\r
589 \r
590         int index = 0;\r
591         for (int i = 0; i < alHeight && index<sSize; i++)\r
592         {\r
593           if(sequences.contains( al.getSequenceAt(i) ) )\r
594             seqs[index++] = al.getSequenceAt(i);\r
595         }\r
596 \r
597         return seqs;\r
598     }\r
599 }\r