2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
3 * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 package jalview.datamodel;
25 import jalview.analysis.*;
26 import jalview.schemes.*;
29 * Collects a set contiguous ranges on a set of sequences
34 public class SequenceGroup
40 Conservation conserve;
44 boolean displayBoxes = true;
46 boolean displayText = true;
48 boolean colourText = false;
50 * after Olivier's non-conserved only character display
52 boolean showUnconserved = false;
57 private Vector sequences = new Vector();
59 * representative sequence for this group (if any)
61 private SequenceI seqrep = null;
65 * Colourscheme applied to group if any */
66 public ColourSchemeI cs;
72 public Color outlineColour = Color.black;
74 public Color idColour = null;
76 public int thresholdTextColour = 0;
78 public Color textColour = Color.black;
80 public Color textColour2 = Color.white;
83 * Creates a new SequenceGroup object.
85 public SequenceGroup()
87 groupName = "JGroup:" + this.hashCode();
91 * Creates a new SequenceGroup object.
100 * first column of group
102 * last column of group
104 public SequenceGroup(Vector sequences, String groupName,
105 ColourSchemeI scheme, boolean displayBoxes, boolean displayText,
106 boolean colourText, int start, int end)
108 this.sequences = sequences;
109 this.groupName = groupName;
110 this.displayBoxes = displayBoxes;
111 this.displayText = displayText;
112 this.colourText = colourText;
116 recalcConservation();
122 public SequenceGroup(SequenceGroup seqsel)
126 sequences=new Vector();
127 Enumeration sq = seqsel.sequences.elements();
128 while (sq.hasMoreElements()) {
129 sequences.addElement(sq.nextElement());
131 if (seqsel.groupName!=null)
133 groupName = new String(seqsel.groupName);
135 displayBoxes = seqsel.displayBoxes;
136 displayText = seqsel.displayText;
137 colourText = seqsel.colourText;
138 startRes = seqsel.startRes;
139 endRes = seqsel.endRes;
141 if (seqsel.description!=null)
142 description = new String(seqsel.description);
143 hidecols = seqsel.hidecols;
144 hidereps = seqsel.hidereps;
145 idColour = seqsel.idColour;
146 outlineColour = seqsel.outlineColour;
147 seqrep = seqsel.seqrep;
148 textColour = seqsel.textColour;
149 textColour2 = seqsel.textColour2;
150 thresholdTextColour = seqsel.thresholdTextColour;
151 width = seqsel.width;
152 if (seqsel.conserve!=null)
154 recalcConservation(); // safer than
155 // aaFrequency = (Vector) seqsel.aaFrequency.clone(); // ??
160 public SequenceI[] getSelectionAsNewSequences(AlignmentI align)
162 int iSize = sequences.size();
163 SequenceI[] seqs = new SequenceI[iSize];
164 SequenceI[] inorder = getSequencesInOrder(align);
166 for (int i = 0, ipos = 0; i < inorder.length; i++)
168 SequenceI seq = inorder[i];
170 seqs[ipos] = seq.getSubSequence(startRes, endRes + 1);
171 if (seqs[ipos] != null)
173 seqs[ipos].setDescription(seq.getDescription());
174 seqs[ipos].setDBRef(seq.getDBRef());
175 seqs[ipos].setSequenceFeatures(seq.getSequenceFeatures());
176 if (seq.getDatasetSequence() != null)
178 seqs[ipos].setDatasetSequence(seq.getDatasetSequence());
181 if (seq.getAnnotation() != null)
183 AlignmentAnnotation[] alann = align.getAlignmentAnnotation();
184 // Only copy annotation that is either a score or referenced by the
185 // alignment's annotation vector
186 for (int a = 0; a < seq.getAnnotation().length; a++)
188 AlignmentAnnotation tocopy = seq.getAnnotation()[a];
191 boolean found = false;
192 for (int pos = 0; pos < alann.length; pos++)
194 if (alann[pos] == tocopy)
203 AlignmentAnnotation newannot = new AlignmentAnnotation(seq
204 .getAnnotation()[a]);
205 newannot.restrict(startRes, endRes);
206 newannot.setSequenceRef(seqs[ipos]);
207 newannot.adjustForAlignment();
208 seqs[ipos].addAlignmentAnnotation(newannot);
218 if (iSize != inorder.length)
220 SequenceI[] nseqs = new SequenceI[iSize];
221 System.arraycopy(seqs, 0, nseqs, 0, iSize);
229 * If sequence ends in gaps, the end residue can be correctly calculated here
235 public int findEndRes(SequenceI seq)
240 for (int j = 0; j < endRes + 1 && j < seq.getLength(); j++)
242 ch = seq.getCharAt(j);
243 if (!jalview.util.Comparison.isGap((ch)))
251 eres += seq.getStart() - 1;
257 public Vector getSequences(Hashtable hiddenReps)
259 if (hiddenReps == null)
265 Vector allSequences = new Vector();
267 for (int i = 0; i < sequences.size(); i++)
269 seq = (SequenceI) sequences.elementAt(i);
270 allSequences.addElement(seq);
271 if (hiddenReps.containsKey(seq))
273 SequenceGroup hsg = (SequenceGroup) hiddenReps.get(seq);
274 for (int h = 0; h < hsg.getSize(); h++)
276 seq2 = hsg.getSequenceAt(h);
277 if (seq2 != seq && !allSequences.contains(seq2))
279 allSequences.addElement(seq2);
289 public SequenceI[] getSequencesAsArray(Hashtable hiddenReps)
291 Vector tmp = getSequences(hiddenReps);
296 SequenceI[] result = new SequenceI[tmp.size()];
297 for (int i = 0; i < result.length; i++)
299 result[i] = (SequenceI) tmp.elementAt(i);
311 * @return DOCUMENT ME!
313 public boolean adjustForRemoveLeft(int col)
315 // return value is true if the group still exists
318 startRes = startRes - col;
323 endRes = endRes - col;
325 if (startRes > endRes)
332 // must delete this group!!
345 * @return DOCUMENT ME!
347 public boolean adjustForRemoveRight(int col)
366 * @return DOCUMENT ME!
368 public String getName()
373 public String getDescription()
384 public void setName(String name)
389 public void setDescription(String desc)
397 * @return DOCUMENT ME!
399 public Conservation getConservation()
410 public void setConservation(Conservation c)
416 * Add s to this sequence group
419 * alignment sequence to be added
421 * true means Group's conservation should be recalculated
423 public void addSequence(SequenceI s, boolean recalc)
425 if (s != null && !sequences.contains(s))
427 sequences.addElement(s);
432 recalcConservation();
437 * calculate residue conservation for group
439 public void recalcConservation()
448 cs.setConsensus(AAFrequency
449 .calculate(sequences, startRes, endRes + 1));
451 if (cs instanceof ClustalxColourScheme)
453 ((ClustalxColourScheme) cs).resetClustalX(sequences, getWidth());
456 if (cs.conservationApplied())
458 Conservation c = new Conservation(groupName,
459 ResidueProperties.propHash, 3, sequences, startRes,
462 c.verdict(false, 25);
464 cs.setConservation(c);
466 if (cs instanceof ClustalxColourScheme)
468 ((ClustalxColourScheme) cs).resetClustalX(sequences, getWidth());
471 } catch (java.lang.OutOfMemoryError err)
474 System.out.println("Out of memory loading groups: " + err);
487 public void addOrRemove(SequenceI s, boolean recalc)
489 if (sequences.contains(s))
491 deleteSequence(s, recalc);
495 addSequence(s, recalc);
507 public void deleteSequence(SequenceI s, boolean recalc)
509 sequences.removeElement(s);
513 recalcConservation();
520 * @return DOCUMENT ME!
522 public int getStartRes()
530 * @return DOCUMENT ME!
532 public int getEndRes()
543 public void setStartRes(int i)
554 public void setEndRes(int i)
562 * @return DOCUMENT ME!
566 return sequences.size();
575 * @return DOCUMENT ME!
577 public SequenceI getSequenceAt(int i)
579 return (SequenceI) sequences.elementAt(i);
588 public void setColourText(boolean state)
596 * @return DOCUMENT ME!
598 public boolean getColourText()
609 public void setDisplayText(boolean state)
617 * @return DOCUMENT ME!
619 public boolean getDisplayText()
630 public void setDisplayBoxes(boolean state)
632 displayBoxes = state;
638 * @return DOCUMENT ME!
640 public boolean getDisplayBoxes()
648 * @return DOCUMENT ME!
650 public int getWidth()
652 // MC This needs to get reset when characters are inserted and deleted
653 if (sequences.size() > 0)
655 width = ((SequenceI) sequences.elementAt(0)).getLength();
658 for (int i = 1; i < sequences.size(); i++)
660 SequenceI seq = (SequenceI) sequences.elementAt(i);
662 if (seq.getLength() > width)
664 width = seq.getLength();
677 public void setOutlineColour(Color c)
685 * @return DOCUMENT ME!
687 public Color getOutlineColour()
689 return outlineColour;
694 * returns the sequences in the group ordered by the ordering given by al.
695 * this used to return an array with null entries regardless, new behaviour is below.
696 * TODO: verify that this does not affect use in applet or application
699 * @return SequenceI[] intersection of sequences in group with al, ordered by al, or null if group does not intersect with al
701 public SequenceI[] getSequencesInOrder(AlignmentI al)
703 int sSize = sequences.size();
704 int alHeight = al.getHeight();
706 SequenceI[] seqs = new SequenceI[sSize];
709 for (int i = 0; i < alHeight && index < sSize; i++)
711 if (sequences.contains(al.getSequenceAt(i)))
713 seqs[index++] = al.getSequenceAt(i);
720 if (index<seqs.length)
722 SequenceI[] dummy = seqs;
723 seqs = new SequenceI[index];
726 seqs[index] = dummy[index];
734 * @return the idColour
736 public Color getIdColour()
743 * the idColour to set
745 public void setIdColour(Color idColour)
747 this.idColour = idColour;
751 * @return the representative sequence for this group
753 public SequenceI getSeqrep()
759 * set the representative sequence for this group.
760 * Note - this affects the interpretation of the Hidereps attribute.
761 * @param seqrep the seqrep to set (null means no sequence representative)
763 public void setSeqrep(SequenceI seqrep)
765 this.seqrep = seqrep;
769 * @return true if group has a sequence representative
771 public boolean hasSeqrep()
773 return seqrep != null;
776 * visibility of rows or represented rows covered by group
778 private boolean hidereps=false;
780 * set visibility of sequences covered by (if no sequence representative is defined)
781 * or represented by this group.
784 public void setHidereps(boolean visibility)
786 hidereps = visibility;
790 * @return true if sequences represented (or covered) by this group should be hidden
792 public boolean isHidereps()
797 * visibility of columns intersecting this group
799 private boolean hidecols=false;
801 * set intended visibility of columns covered by this group
804 public void setHideCols(boolean visibility)
806 hidecols = visibility;
810 * @return true if columns covered by group should be hidden
812 public boolean isHideCols()
817 * create a new sequence group from the intersection of this group
818 * with an alignment Hashtable of hidden representatives
820 * @param alignment (may not be null)
821 * @param hashtable (may be null)
822 * @return new group containing sequences common to this group and alignment
824 public SequenceGroup intersect(AlignmentI alignment, Hashtable hashtable)
826 SequenceGroup sgroup = new SequenceGroup(this);
827 Enumeration en = getSequences(hashtable).elements();
828 while (en.hasMoreElements())
830 SequenceI elem = (SequenceI) en.nextElement();
831 if (alignment.getSequences().contains(elem))
833 sgroup.addSequence(elem, false);
840 * @return the showUnconserved
842 public boolean getShowunconserved()
844 return showUnconserved;
848 * @param showUnconserved the showUnconserved to set
850 public void setShowunconserved(boolean displayNonconserved)
852 this.showUnconserved = displayNonconserved;
855 public AlignmentAnnotation getConsensus()
857 // TODO get or calculate and get consensus annotation row for this group
858 this.conserve.getConsSequence();