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;
52 private Vector sequences = new Vector();
54 * representative sequence for this group (if any)
56 private SequenceI seqrep = null;
60 * Colourscheme applied to group if any */
61 public ColourSchemeI cs;
67 public Color outlineColour = Color.black;
69 public Color idColour = null;
71 public int thresholdTextColour = 0;
73 public Color textColour = Color.black;
75 public Color textColour2 = Color.white;
78 * Creates a new SequenceGroup object.
80 public SequenceGroup()
82 groupName = "JGroup:" + this.hashCode();
86 * Creates a new SequenceGroup object.
95 * first column of group
97 * last column of group
99 public SequenceGroup(Vector sequences, String groupName,
100 ColourSchemeI scheme, boolean displayBoxes, boolean displayText,
101 boolean colourText, int start, int end)
103 this.sequences = sequences;
104 this.groupName = groupName;
105 this.displayBoxes = displayBoxes;
106 this.displayText = displayText;
107 this.colourText = colourText;
111 recalcConservation();
117 public SequenceGroup(SequenceGroup seqsel)
121 sequences=new Vector();
122 Enumeration sq = seqsel.sequences.elements();
123 while (sq.hasMoreElements()) {
124 sequences.addElement(sq.nextElement());
126 groupName = new String(seqsel.groupName);
127 displayBoxes = seqsel.displayBoxes;
128 displayText = seqsel.displayText;
129 colourText = seqsel.colourText;
130 startRes = seqsel.startRes;
131 endRes = seqsel.endRes;
133 if (seqsel.description!=null)
134 description = new String(seqsel.description);
135 groupName = new String(seqsel.groupName);
136 hidecols = seqsel.hidecols;
137 hidereps = seqsel.hidereps;
138 idColour = seqsel.idColour;
139 outlineColour = seqsel.outlineColour;
140 seqrep = seqsel.seqrep;
141 textColour = seqsel.textColour;
142 textColour2 = seqsel.textColour2;
143 thresholdTextColour = seqsel.thresholdTextColour;
144 width = seqsel.width;
145 if (seqsel.conserve!=null)
147 recalcConservation(); // safer than
148 // aaFrequency = (Vector) seqsel.aaFrequency.clone(); // ??
153 public SequenceI[] getSelectionAsNewSequences(AlignmentI align)
155 int iSize = sequences.size();
156 SequenceI[] seqs = new SequenceI[iSize];
157 SequenceI[] inorder = getSequencesInOrder(align);
159 for (int i = 0, ipos = 0; i < inorder.length; i++)
161 SequenceI seq = inorder[i];
163 seqs[ipos] = seq.getSubSequence(startRes, endRes + 1);
164 if (seqs[ipos] != null)
166 seqs[ipos].setDescription(seq.getDescription());
167 seqs[ipos].setDBRef(seq.getDBRef());
168 seqs[ipos].setSequenceFeatures(seq.getSequenceFeatures());
169 if (seq.getDatasetSequence() != null)
171 seqs[ipos].setDatasetSequence(seq.getDatasetSequence());
174 if (seq.getAnnotation() != null)
176 AlignmentAnnotation[] alann = align.getAlignmentAnnotation();
177 // Only copy annotation that is either a score or referenced by the
178 // alignment's annotation vector
179 for (int a = 0; a < seq.getAnnotation().length; a++)
181 AlignmentAnnotation tocopy = seq.getAnnotation()[a];
184 boolean found = false;
185 for (int pos = 0; pos < alann.length; pos++)
187 if (alann[pos] == tocopy)
196 AlignmentAnnotation newannot = new AlignmentAnnotation(seq
197 .getAnnotation()[a]);
198 newannot.restrict(startRes, endRes);
199 newannot.setSequenceRef(seqs[ipos]);
200 newannot.adjustForAlignment();
201 seqs[ipos].addAlignmentAnnotation(newannot);
211 if (iSize != inorder.length)
213 SequenceI[] nseqs = new SequenceI[iSize];
214 System.arraycopy(seqs, 0, nseqs, 0, iSize);
222 * If sequence ends in gaps, the end residue can be correctly calculated here
228 public int findEndRes(SequenceI seq)
233 for (int j = 0; j < endRes + 1 && j < seq.getLength(); j++)
235 ch = seq.getCharAt(j);
236 if (!jalview.util.Comparison.isGap((ch)))
244 eres += seq.getStart() - 1;
250 public Vector getSequences(Hashtable hiddenReps)
252 if (hiddenReps == null)
258 Vector allSequences = new Vector();
260 for (int i = 0; i < sequences.size(); i++)
262 seq = (SequenceI) sequences.elementAt(i);
263 allSequences.addElement(seq);
264 if (hiddenReps.containsKey(seq))
266 SequenceGroup hsg = (SequenceGroup) hiddenReps.get(seq);
267 for (int h = 0; h < hsg.getSize(); h++)
269 seq2 = hsg.getSequenceAt(h);
270 if (seq2 != seq && !allSequences.contains(seq2))
272 allSequences.addElement(seq2);
282 public SequenceI[] getSequencesAsArray(Hashtable hiddenReps)
284 Vector tmp = getSequences(hiddenReps);
289 SequenceI[] result = new SequenceI[tmp.size()];
290 for (int i = 0; i < result.length; i++)
292 result[i] = (SequenceI) tmp.elementAt(i);
304 * @return DOCUMENT ME!
306 public boolean adjustForRemoveLeft(int col)
308 // return value is true if the group still exists
311 startRes = startRes - col;
316 endRes = endRes - col;
318 if (startRes > endRes)
325 // must delete this group!!
338 * @return DOCUMENT ME!
340 public boolean adjustForRemoveRight(int col)
359 * @return DOCUMENT ME!
361 public String getName()
366 public String getDescription()
377 public void setName(String name)
382 public void setDescription(String desc)
390 * @return DOCUMENT ME!
392 public Conservation getConservation()
403 public void setConservation(Conservation c)
409 * Add s to this sequence group
412 * alignment sequence to be added
414 * true means Group's conservation should be recalculated
416 public void addSequence(SequenceI s, boolean recalc)
418 if (s != null && !sequences.contains(s))
420 sequences.addElement(s);
425 recalcConservation();
430 * calculate residue conservation for group
432 public void recalcConservation()
441 cs.setConsensus(AAFrequency
442 .calculate(sequences, startRes, endRes + 1));
444 if (cs instanceof ClustalxColourScheme)
446 ((ClustalxColourScheme) cs).resetClustalX(sequences, getWidth());
449 if (cs.conservationApplied())
451 Conservation c = new Conservation(groupName,
452 ResidueProperties.propHash, 3, sequences, startRes,
455 c.verdict(false, 25);
457 cs.setConservation(c);
459 if (cs instanceof ClustalxColourScheme)
461 ((ClustalxColourScheme) cs).resetClustalX(sequences, getWidth());
464 } catch (java.lang.OutOfMemoryError err)
467 System.out.println("Out of memory loading groups: " + err);
480 public void addOrRemove(SequenceI s, boolean recalc)
482 if (sequences.contains(s))
484 deleteSequence(s, recalc);
488 addSequence(s, recalc);
500 public void deleteSequence(SequenceI s, boolean recalc)
502 sequences.removeElement(s);
506 recalcConservation();
513 * @return DOCUMENT ME!
515 public int getStartRes()
523 * @return DOCUMENT ME!
525 public int getEndRes()
536 public void setStartRes(int i)
547 public void setEndRes(int i)
555 * @return DOCUMENT ME!
559 return sequences.size();
568 * @return DOCUMENT ME!
570 public SequenceI getSequenceAt(int i)
572 return (SequenceI) sequences.elementAt(i);
581 public void setColourText(boolean state)
589 * @return DOCUMENT ME!
591 public boolean getColourText()
602 public void setDisplayText(boolean state)
610 * @return DOCUMENT ME!
612 public boolean getDisplayText()
623 public void setDisplayBoxes(boolean state)
625 displayBoxes = state;
631 * @return DOCUMENT ME!
633 public boolean getDisplayBoxes()
641 * @return DOCUMENT ME!
643 public int getWidth()
645 // MC This needs to get reset when characters are inserted and deleted
646 if (sequences.size() > 0)
648 width = ((SequenceI) sequences.elementAt(0)).getLength();
651 for (int i = 1; i < sequences.size(); i++)
653 SequenceI seq = (SequenceI) sequences.elementAt(i);
655 if (seq.getLength() > width)
657 width = seq.getLength();
670 public void setOutlineColour(Color c)
678 * @return DOCUMENT ME!
680 public Color getOutlineColour()
682 return outlineColour;
687 * returns the sequences in the group ordered by the ordering given by al
691 * @return SequenceI[]
693 public SequenceI[] getSequencesInOrder(AlignmentI al)
695 int sSize = sequences.size();
696 int alHeight = al.getHeight();
698 SequenceI[] seqs = new SequenceI[sSize];
701 for (int i = 0; i < alHeight && index < sSize; i++)
703 if (sequences.contains(al.getSequenceAt(i)))
705 seqs[index++] = al.getSequenceAt(i);
713 * @return the idColour
715 public Color getIdColour()
722 * the idColour to set
724 public void setIdColour(Color idColour)
726 this.idColour = idColour;
730 * @return the representative sequence for this group
732 public SequenceI getSeqrep()
738 * set the representative sequence for this group.
739 * Note - this affects the interpretation of the Hidereps attribute.
740 * @param seqrep the seqrep to set (null means no sequence representative)
742 public void setSeqrep(SequenceI seqrep)
744 this.seqrep = seqrep;
748 * @return true if group has a sequence representative
750 public boolean hasSeqrep()
752 return seqrep != null;
755 * visibility of rows or represented rows covered by group
757 private boolean hidereps=false;
759 * set visibility of sequences covered by (if no sequence representative is defined)
760 * or represented by this group.
763 public void setHidereps(boolean visibility)
765 hidereps = visibility;
769 * @return true if sequences represented (or covered) by this group should be hidden
771 public boolean isHidereps()
776 * visibility of columns intersecting this group
778 private boolean hidecols=false;
780 * set intended visibility of columns covered by this group
783 public void setHideCols(boolean visibility)
785 hidecols = visibility;
789 * @return true if columns covered by group should be hidden
791 public boolean isHideCols()
796 * create a new sequence group from the intersection of this group
797 * with an alignment Hashtable of hidden representatives
799 * @param alignment (may not be null)
800 * @param hashtable (may be null)
801 * @return new group containing sequences common to this group and alignment
803 public SequenceGroup intersect(AlignmentI alignment, Hashtable hashtable)
805 SequenceGroup sgroup = new SequenceGroup(this);
806 Enumeration en = getSequences(hashtable).elements();
807 while (en.hasMoreElements())
809 SequenceI elem = (SequenceI) en.nextElement();
810 if (alignment.getSequences().contains(elem))
812 sgroup.addSequence(elem, false);