2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2006 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;
21 import jalview.analysis.*;
25 /** Data structure to hold and manipulate a multiple sequence alignment
27 public class Alignment implements AlignmentI
29 protected Alignment dataset;
30 protected Vector sequences;
31 protected Vector groups = new Vector();
32 protected char gapCharacter = '-';
33 protected int type = NUCLEOTIDE;
34 public static final int PROTEIN = 0;
35 public static final int NUCLEOTIDE = 1;
38 public AlignmentAnnotation[] annotations;
40 HiddenSequences hiddenSequences = new HiddenSequences(this);
42 private void initAlignment(SequenceI[] seqs) {
45 if( jalview.util.Comparison.isNucleotide(seqs))
50 sequences = new Vector();
52 for (i = 0; i < seqs.length; i++)
54 sequences.addElement(seqs[i]);
58 /** Make an alignment from an array of Sequences.
62 public Alignment(SequenceI[] seqs)
67 * Make a new alignment from an array of SeqCigars
68 * @param seqs SeqCigar[]
70 public Alignment(SeqCigar[] alseqs) {
71 SequenceI[] seqs = SeqCigar.createAlignmentSequences(alseqs, gapCharacter, new ColumnSelection(), null);
75 * Make a new alignment from an CigarArray
76 * JBPNote - can only do this when compactAlignment does not contain hidden regions.
77 * JBPNote - must also check that compactAlignment resolves to a set of SeqCigars - or construct them appropriately.
78 * @param compactAlignment CigarArray
80 public static AlignmentI createAlignment(CigarArray compactAlignment) {
81 throw new Error("Alignment(CigarArray) not yet implemented");
82 // this(compactAlignment.refCigars);
88 * @return DOCUMENT ME!
90 public Vector getSequences()
95 public SequenceI [] getSequencesArray()
97 SequenceI [] reply = new SequenceI[sequences.size()];
98 for(int i=0; i<sequences.size(); i++)
100 reply[i] = (SequenceI)sequences.elementAt(i);
108 * @param i DOCUMENT ME!
110 * @return DOCUMENT ME!
112 public SequenceI getSequenceAt(int i)
114 if (i < sequences.size())
116 return (SequenceI) sequences.elementAt(i);
122 /** Adds a sequence to the alignment. Recalculates maxLength and size.
126 public void addSequence(SequenceI snew)
130 if(snew.getDatasetSequence()!=null)
132 getDataset().addSequence(snew.getDatasetSequence());
136 Sequence ds = new Sequence(snew.getName(),
137 AlignSeq.extractGaps("-. ",
138 snew.getSequenceAsString()),
142 snew.setDatasetSequence(ds);
143 getDataset().addSequence(ds);
146 sequences.addElement(snew);
148 hiddenSequences.adjustHeightSequenceAdded();
152 /** Adds a sequence to the alignment. Recalculates maxLength and size.
156 public void setSequenceAt(int i, SequenceI snew)
158 SequenceI oldseq = getSequenceAt(i);
159 deleteSequence(oldseq);
161 sequences.setElementAt(snew, i);
167 * @return DOCUMENT ME!
169 public Vector getGroups()
177 * @param s DOCUMENT ME!
179 public void deleteSequence(SequenceI s)
181 deleteSequence(findIndex(s));
187 * @param i DOCUMENT ME!
189 public void deleteSequence(int i)
191 if(i>-1 && i<getHeight())
193 sequences.removeElementAt(i);
194 hiddenSequences.adjustHeightSequenceDeleted(i);
200 public SequenceGroup findGroup(SequenceI s)
202 for (int i = 0; i < this.groups.size(); i++)
204 SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
206 if (sg.getSequences(null).contains(s))
218 * @param s DOCUMENT ME!
220 * @return DOCUMENT ME!
222 public SequenceGroup[] findAllGroups(SequenceI s)
224 Vector temp = new Vector();
226 int gSize = groups.size();
227 for (int i = 0; i < gSize; i++)
229 SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
230 if(sg==null || sg.getSequences(null)==null)
232 this.deleteGroup(sg);
237 if (sg.getSequences(null).contains(s))
243 SequenceGroup[] ret = new SequenceGroup[temp.size()];
245 for (int i = 0; i < temp.size(); i++)
247 ret[i] = (SequenceGroup) temp.elementAt(i);
256 public void addGroup(SequenceGroup sg)
258 if (!groups.contains(sg))
260 if(hiddenSequences.getSize()>0)
262 int i, iSize = sg.getSize();
263 for (i = 0; i < iSize; i++)
265 if (!sequences.contains(sg.getSequenceAt(i)))
267 sg.deleteSequence(sg.getSequenceAt(i), false);
273 if (sg.getSize() < 1)
277 groups.addElement(sg);
284 public void deleteAllGroups()
286 groups.removeAllElements();
290 public void deleteGroup(SequenceGroup g)
292 if (groups.contains(g))
294 groups.removeElement(g);
299 public SequenceI findName(String name)
303 while (i < sequences.size())
305 if (getSequenceAt(i).getName().equals(name))
307 return getSequenceAt(i);
316 public SequenceI [] findSequenceMatch(String name)
318 Vector matches = new Vector();
321 while (i < sequences.size())
323 if (getSequenceAt(i).getName().equals(name))
325 matches.addElement(getSequenceAt(i));
330 SequenceI [] result = new SequenceI[matches.size()];
331 for(i=0; i<result.length; i++)
332 result[i] = (SequenceI)matches.elementAt(i);
340 public int findIndex(SequenceI s)
344 while (i < sequences.size())
346 if (s == getSequenceAt(i))
360 * @return DOCUMENT ME!
362 public int getHeight()
364 return sequences.size();
370 * @return DOCUMENT ME!
372 public int getWidth()
376 for (int i = 0; i < sequences.size(); i++)
378 if (getSequenceAt(i).getLength() > maxLength)
380 maxLength = getSequenceAt(i).getLength();
391 * @param gc DOCUMENT ME!
393 public void setGapCharacter(char gc)
397 for (int i = 0; i < sequences.size(); i++)
399 Sequence seq = (Sequence) sequences.elementAt(i);
400 seq.setSequence(seq.getSequenceAsString()
411 * @return DOCUMENT ME!
413 public char getGapCharacter()
422 * @return DOCUMENT ME!
424 public boolean isAligned()
426 int width = getWidth();
428 for (int i = 0; i < sequences.size(); i++)
430 if (getSequenceAt(i).getLength() != width)
442 * @param aa DOCUMENT ME!
444 public void deleteAnnotation(AlignmentAnnotation aa)
448 if (annotations != null)
450 aSize = annotations.length;
456 AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize - 1];
460 for (int i = 0; i < aSize; i++)
462 if (annotations[i] == aa)
467 temp[tIndex] = annotations[i];
478 * @param aa DOCUMENT ME!
480 public void addAnnotation(AlignmentAnnotation aa)
483 if (annotations != null)
485 aSize = annotations.length + 1;
488 AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize];
496 for (i = 0; i < (aSize-1); i++)
498 temp[i] = annotations[i];
505 public void setAnnotationIndex(AlignmentAnnotation aa, int index)
507 if(aa==null || annotations==null || annotations.length-1<index)
510 int aSize = annotations.length;
511 AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize];
515 for (int i = 0; i < aSize; i++)
521 temp[i] = annotations[i];
523 temp[i] = annotations[i-1];
532 * @return DOCUMENT ME!
534 public AlignmentAnnotation[] getAlignmentAnnotation()
539 public void setNucleotide(boolean b)
547 public boolean isNucleotide()
555 public void setDataset(Alignment data)
557 if(dataset==null && data==null)
559 // Create a new dataset for this alignment.
560 // Can only be done once, if dataset is not null
561 // This will not be performed
562 Sequence[] seqs = new Sequence[getHeight()];
563 SequenceI currentSeq;
564 for (int i = 0; i < getHeight(); i++)
566 currentSeq = getSequenceAt(i);
567 if(currentSeq.getDatasetSequence()!=null)
569 seqs[i] = (Sequence)currentSeq.getDatasetSequence();
573 seqs[i] = new Sequence(currentSeq.getName(),
574 AlignSeq.extractGaps(
575 jalview.util.Comparison.GapChars,
576 currentSeq.getSequenceAsString()
578 currentSeq.getStart(),
579 currentSeq.getEnd());
580 seqs[i].sequenceFeatures = currentSeq.getSequenceFeatures();
581 seqs[i].setDescription(currentSeq.getDescription());
582 getSequenceAt(i).setSequenceFeatures(null);
583 getSequenceAt(i).setDatasetSequence(seqs[i]);
587 dataset = new Alignment(seqs);
589 else if(dataset==null && data!=null)
595 public Alignment getDataset()
600 public boolean padGaps()
602 boolean modified=false;
604 //Remove excess gaps from the end of alignment
608 for (int i = 0; i < sequences.size(); i++)
610 current = getSequenceAt(i);
611 for (int j = current.getLength(); j > maxLength; j--)
613 if (j > maxLength && !jalview.util.Comparison.isGap(
614 current.getCharAt(j)))
625 for (int i = 0; i < sequences.size();
628 current = getSequenceAt(i);
629 cLength = current.getLength();
631 if (cLength < maxLength)
633 current.insertCharAt(cLength,
634 maxLength-cLength, gapCharacter);
637 else if(current.getLength() > maxLength)
639 current.deleteChars(maxLength, current.getLength());
645 public HiddenSequences getHiddenSequences()
647 return hiddenSequences;
650 public CigarArray getCompactAlignment()
652 SeqCigar alseqs[] = new SeqCigar[sequences.size()];
653 for (int i=0; i<sequences.size(); i++) {
654 alseqs[i] = new SeqCigar((SequenceI) sequences.elementAt(i));
656 CigarArray cal = new CigarArray(alseqs);
657 cal.addOperation(CigarArray.M, getWidth());