2 * Jalview - A Sequence Alignment Editor and Viewer
\r
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
\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
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
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
19 package jalview.datamodel;
\r
21 import jalview.analysis.*;
\r
23 import jalview.util.*;
\r
28 /** Data structure to hold and manipulate a multiple sequence alignment
\r
30 public class Alignment implements AlignmentI
\r
32 protected Vector sequences;
\r
33 protected Vector groups = new Vector();
\r
34 protected Vector superGroup = new Vector();
\r
35 protected char gapCharacter = '-';
\r
37 /** DOCUMENT ME!! */
\r
38 public AlignmentAnnotation[] annotations;
\r
40 /** DOCUMENT ME!! */
\r
41 public boolean featuresAdded = false;
\r
43 /** Make an alignment from an array of Sequences.
\r
47 public Alignment(SequenceI[] seqs)
\r
49 sequences = new Vector();
\r
51 for (int i = 0; i < seqs.length; i++)
\r
53 sequences.addElement(seqs[i]);
\r
62 * @return DOCUMENT ME!
\r
64 public Vector getSequences()
\r
72 * @param i DOCUMENT ME!
\r
74 * @return DOCUMENT ME!
\r
76 public SequenceI getSequenceAt(int i)
\r
78 if (i < sequences.size())
\r
80 return (SequenceI) sequences.elementAt(i);
\r
86 /** Adds a sequence to the alignment. Recalculates maxLength and size.
\r
90 public void addSequence(SequenceI snew)
\r
92 sequences.addElement(snew);
\r
98 * @param seq DOCUMENT ME!
\r
100 public void addSequence(SequenceI[] seq)
\r
102 for (int i = 0; i < seq.length; i++)
\r
104 addSequence(seq[i]);
\r
108 /** Adds a sequence to the alignment. Recalculates maxLength and size.
\r
112 public void setSequenceAt(int i, SequenceI snew)
\r
114 SequenceI oldseq = getSequenceAt(i);
\r
115 deleteSequence(oldseq);
\r
117 sequences.setElementAt(snew, i);
\r
123 * @return DOCUMENT ME!
\r
125 public Vector getGroups()
\r
130 /** Takes out columns consisting entirely of gaps (-,.," ")
\r
132 public void removeGaps()
\r
135 int iSize = getWidth();
\r
137 for (int i = 0; i < iSize; i++)
\r
139 boolean delete = true;
\r
141 for (int j = 0; j < getHeight(); j++)
\r
143 current = getSequenceAt(j);
\r
145 if (current.getLength() > i)
\r
147 /* MC Should move this to a method somewhere */
\r
148 if (!jalview.util.Comparison.isGap(current.getCharAt(i)))
\r
157 deleteColumns(i, i);
\r
164 /** Removes a range of columns (start to end inclusive).
\r
166 * @param start Start column in the alignment
\r
167 * @param end End column in the alignment
\r
169 public void deleteColumns(int start, int end)
\r
171 deleteColumns(0, getHeight() - 1, start, end);
\r
177 * @param seq1 DOCUMENT ME!
\r
178 * @param seq2 DOCUMENT ME!
\r
179 * @param start DOCUMENT ME!
\r
180 * @param end DOCUMENT ME!
\r
182 public void deleteColumns(int seq1, int seq2, int start, int end)
\r
184 for (int i = 0; i <= (end - start); i++)
\r
186 for (int j = seq1; j <= seq2; j++)
\r
188 getSequenceAt(j).deleteCharAt(start);
\r
196 * @param i DOCUMENT ME!
\r
198 public void trimLeft(int i)
\r
200 for (int j = 0; j < getHeight(); j++)
\r
202 SequenceI s = getSequenceAt(j);
\r
203 int newstart = s.findPosition(i);
\r
205 s.setStart(newstart);
\r
206 s.setSequence(s.getSequence().substring(i));
\r
213 * @param i DOCUMENT ME!
\r
215 public void trimRight(int i)
\r
217 for (int j = 0; j < getHeight(); j++)
\r
219 SequenceI s = getSequenceAt(j);
\r
220 int newend = s.findPosition(i);
\r
223 s.setSequence(s.getSequence().substring(0, i + 1));
\r
230 * @param s DOCUMENT ME!
\r
232 public void deleteSequence(SequenceI s)
\r
234 for (int i = 0; i < getHeight(); i++)
\r
236 if (getSequenceAt(i) == s)
\r
246 * @param i DOCUMENT ME!
\r
248 public void deleteSequence(int i)
\r
250 sequences.removeElementAt(i);
\r
256 * @param threshold DOCUMENT ME!
\r
257 * @param sel DOCUMENT ME!
\r
259 * @return DOCUMENT ME!
\r
261 public Vector removeRedundancy(float threshold, Vector sel)
\r
263 Vector del = new Vector();
\r
265 for (int i = 1; i < sel.size(); i++)
\r
267 for (int j = 0; j < i; j++)
\r
269 // Only do the comparison if either have not been deleted
\r
270 if (!del.contains((SequenceI) sel.elementAt(i)) ||
\r
271 !del.contains((SequenceI) sel.elementAt(j)))
\r
273 // use PID instead of Comparison (which is really not pleasant)
\r
274 float pid = Comparison.PID((SequenceI) sel.elementAt(j),
\r
275 (SequenceI) sel.elementAt(i));
\r
277 if (pid >= threshold)
\r
279 // Delete the shortest one
\r
280 if (((SequenceI) sel.elementAt(j)).getSequence().length() > ((SequenceI) sel
\r
282 i)).getSequence().length())
\r
284 del.addElement(sel.elementAt(i));
\r
288 del.addElement(sel.elementAt(i));
\r
295 // Now delete the sequences
\r
296 for (int i = 0; i < del.size(); i++)
\r
298 deleteSequence((SequenceI) del.elementAt(i));
\r
305 public SequenceGroup findGroup(int i)
\r
307 return findGroup(getSequenceAt(i));
\r
311 public SequenceGroup findGroup(SequenceI s)
\r
313 for (int i = 0; i < this.groups.size(); i++)
\r
315 SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
\r
317 if (sg.sequences.contains(s))
\r
329 * @param s DOCUMENT ME!
\r
331 * @return DOCUMENT ME!
\r
333 public SequenceGroup[] findAllGroups(SequenceI s)
\r
335 Vector temp = new Vector();
\r
337 int gSize = groups.size();
\r
338 for (int i = 0; i < gSize; i++)
\r
340 SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
\r
341 if(sg==null || sg.sequences==null)
\r
343 this.deleteGroup(sg);
\r
348 if (sg.sequences.contains(s))
\r
350 temp.addElement(sg);
\r
354 SequenceGroup[] ret = new SequenceGroup[temp.size()];
\r
356 for (int i = 0; i < temp.size(); i++)
\r
358 ret[i] = (SequenceGroup) temp.elementAt(i);
\r
367 * @param sg DOCUMENT ME!
\r
369 public void addSuperGroup(SuperGroup sg)
\r
371 superGroup.addElement(sg);
\r
377 * @param sg DOCUMENT ME!
\r
379 public void removeSuperGroup(SuperGroup sg)
\r
381 superGroup.removeElement(sg);
\r
387 * @param sg DOCUMENT ME!
\r
389 * @return DOCUMENT ME!
\r
391 public SuperGroup getSuperGroup(SequenceGroup sg)
\r
393 for (int i = 0; i < this.superGroup.size(); i++)
\r
395 SuperGroup temp = (SuperGroup) superGroup.elementAt(i);
\r
397 if (temp.sequenceGroups.contains(sg))
\r
407 public void addGroup(SequenceGroup sg)
\r
409 if (!groups.contains(sg))
\r
411 groups.addElement(sg);
\r
418 public void deleteAllGroups()
\r
420 groups.removeAllElements();
\r
421 superGroup.removeAllElements();
\r
425 while (i < sequences.size())
\r
427 SequenceI s = getSequenceAt(i);
\r
428 s.setColor(java.awt.Color.white);
\r
434 public void deleteGroup(SequenceGroup g)
\r
436 if (groups.contains(g))
\r
438 groups.removeElement(g);
\r
443 public SequenceI findName(String name)
\r
447 while (i < sequences.size())
\r
449 SequenceI s = getSequenceAt(i);
\r
451 if (s.getName().equals(name))
\r
463 public SequenceI findbyDisplayId(String name)
\r
467 while (i < sequences.size())
\r
469 SequenceI s = getSequenceAt(i);
\r
471 if (s.getDisplayId().equals(name))
\r
483 public int findIndex(SequenceI s)
\r
487 while (i < sequences.size())
\r
489 if (s == getSequenceAt(i))
\r
503 * @return DOCUMENT ME!
\r
505 public int getHeight()
\r
507 return sequences.size();
\r
513 * @return DOCUMENT ME!
\r
515 public int getWidth()
\r
517 int maxLength = -1;
\r
519 for (int i = 0; i < sequences.size(); i++)
\r
521 if (getSequenceAt(i).getLength() > maxLength)
\r
523 maxLength = getSequenceAt(i).getLength();
\r
533 * @return DOCUMENT ME!
\r
535 public int getMaxIdLength()
\r
540 while (i < sequences.size())
\r
542 SequenceI seq = getSequenceAt(i);
\r
543 String tmp = seq.getName() + "/" + seq.getStart() + "-" +
\r
546 if (tmp.length() > max)
\r
548 max = tmp.length();
\r
560 * @param gc DOCUMENT ME!
\r
562 public void setGapCharacter(char gc)
\r
566 for (int i = 0; i < sequences.size(); i++)
\r
568 Sequence seq = (Sequence) sequences.elementAt(i);
\r
569 seq.sequence = seq.sequence.replace('.', gc);
\r
570 seq.sequence = seq.sequence.replace('-', gc);
\r
571 seq.sequence = seq.sequence.replace(' ', gc);
\r
578 * @return DOCUMENT ME!
\r
580 public char getGapCharacter()
\r
582 return gapCharacter;
\r
588 * @return DOCUMENT ME!
\r
590 public Vector getAAFrequency()
\r
592 return AAFrequency.calculate(sequences, 0, getWidth());
\r
598 * @return DOCUMENT ME!
\r
600 public boolean isAligned()
\r
602 int width = getWidth();
\r
604 for (int i = 0; i < sequences.size(); i++)
\r
606 if (getSequenceAt(i).getLength() != width)
\r
618 * @param aa DOCUMENT ME!
\r
620 public void deleteAnnotation(AlignmentAnnotation aa)
\r
624 if (annotations != null)
\r
626 aSize = annotations.length;
\r
629 AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize - 1];
\r
633 for (int i = 0; i < aSize; i++)
\r
635 if (annotations[i] == aa)
\r
640 temp[tIndex] = annotations[i];
\r
644 annotations = temp;
\r
650 * @param aa DOCUMENT ME!
\r
652 public void addAnnotation(AlignmentAnnotation aa)
\r
656 if (annotations != null)
\r
658 aSize = annotations.length + 1;
\r
661 AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize];
\r
666 for (i = 0; i < (aSize - 1); i++)
\r
668 temp[i] = annotations[i];
\r
674 annotations = temp;
\r
680 * @return DOCUMENT ME!
\r
682 public AlignmentAnnotation[] getAlignmentAnnotation()
\r
684 return annotations;
\r