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