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