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