2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2007 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;
23 import jalview.analysis.*;
25 /** Data structure to hold and manipulate a multiple sequence alignment
27 public class Alignment
30 protected Alignment dataset;
31 protected Vector sequences;
32 protected Vector groups = new Vector();
33 protected char gapCharacter = '-';
34 protected int type = NUCLEOTIDE;
35 public static final int PROTEIN = 0;
36 public static final int NUCLEOTIDE = 1;
39 public AlignmentAnnotation[] annotations;
41 HiddenSequences hiddenSequences = new HiddenSequences(this);
43 public Hashtable alignmentProperties;
45 private void initAlignment(SequenceI[] seqs)
49 if (jalview.util.Comparison.isNucleotide(seqs))
58 sequences = new Vector();
60 for (i = 0; i < seqs.length; i++)
62 sequences.addElement(seqs[i]);
67 /** Make an alignment from an array of Sequences.
71 public Alignment(SequenceI[] seqs)
77 * Make a new alignment from an array of SeqCigars
78 * @param seqs SeqCigar[]
80 public Alignment(SeqCigar[] alseqs)
82 SequenceI[] seqs = SeqCigar.createAlignmentSequences(alseqs, gapCharacter,
83 new ColumnSelection(), null);
88 * Make a new alignment from an CigarArray
89 * JBPNote - can only do this when compactAlignment does not contain hidden regions.
90 * JBPNote - must also check that compactAlignment resolves to a set of SeqCigars - or construct them appropriately.
91 * @param compactAlignment CigarArray
93 public static AlignmentI createAlignment(CigarArray compactAlignment)
95 throw new Error("Alignment(CigarArray) not yet implemented");
96 // this(compactAlignment.refCigars);
102 * @return DOCUMENT ME!
104 public Vector getSequences()
109 public SequenceI[] getSequencesArray()
111 SequenceI[] reply = new SequenceI[sequences.size()];
112 for (int i = 0; i < sequences.size(); i++)
114 reply[i] = (SequenceI) sequences.elementAt(i);
122 * @param i DOCUMENT ME!
124 * @return DOCUMENT ME!
126 public SequenceI getSequenceAt(int i)
128 if (i < sequences.size())
130 return (SequenceI) sequences.elementAt(i);
136 /** Adds a sequence to the alignment. Recalculates maxLength and size.
140 public void addSequence(SequenceI snew)
144 // maintain dataset integrity
145 if (snew.getDatasetSequence() != null)
147 getDataset().addSequence(snew.getDatasetSequence());
151 // derive new sequence
152 SequenceI adding = snew.deriveSequence();
153 getDataset().addSequence(adding.getDatasetSequence());
157 if (sequences==null) {
158 initAlignment(new SequenceI[] { snew });
160 sequences.addElement(snew);
162 if (hiddenSequences!=null)
163 hiddenSequences.adjustHeightSequenceAdded();
166 /** Adds a sequence to the alignment. Recalculates maxLength and size.
170 public void setSequenceAt(int i, SequenceI snew)
172 SequenceI oldseq = getSequenceAt(i);
173 deleteSequence(oldseq);
175 sequences.setElementAt(snew, i);
181 * @return DOCUMENT ME!
183 public Vector getGroups()
188 public void finalize()
190 if(getDataset()!=null)
191 getDataset().finalize();
197 hiddenSequences = null;
204 * @param s DOCUMENT ME!
206 public void deleteSequence(SequenceI s)
208 deleteSequence(findIndex(s));
214 * @param i DOCUMENT ME!
216 public void deleteSequence(int i)
218 if (i > -1 && i < getHeight())
220 sequences.removeElementAt(i);
221 hiddenSequences.adjustHeightSequenceDeleted(i);
226 public SequenceGroup findGroup(SequenceI s)
228 for (int i = 0; i < this.groups.size(); i++)
230 SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
232 if (sg.getSequences(null).contains(s))
244 * @param s DOCUMENT ME!
246 * @return DOCUMENT ME!
248 public SequenceGroup[] findAllGroups(SequenceI s)
250 Vector temp = new Vector();
252 int gSize = groups.size();
253 for (int i = 0; i < gSize; i++)
255 SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
256 if (sg == null || sg.getSequences(null) == null)
258 this.deleteGroup(sg);
263 if (sg.getSequences(null).contains(s))
269 SequenceGroup[] ret = new SequenceGroup[temp.size()];
271 for (int i = 0; i < temp.size(); i++)
273 ret[i] = (SequenceGroup) temp.elementAt(i);
280 public void addGroup(SequenceGroup sg)
282 if (!groups.contains(sg))
284 if (hiddenSequences.getSize() > 0)
286 int i, iSize = sg.getSize();
287 for (i = 0; i < iSize; i++)
289 if (!sequences.contains(sg.getSequenceAt(i)))
291 sg.deleteSequence(sg.getSequenceAt(i), false);
297 if (sg.getSize() < 1)
303 groups.addElement(sg);
310 public void deleteAllGroups()
312 groups.removeAllElements();
316 public void deleteGroup(SequenceGroup g)
318 if (groups.contains(g))
320 groups.removeElement(g);
325 public SequenceI findName(String name)
329 while (i < sequences.size())
331 if (getSequenceAt(i).getName().equals(name))
333 return getSequenceAt(i);
342 public SequenceI[] findSequenceMatch(String name)
344 Vector matches = new Vector();
347 while (i < sequences.size())
349 if (getSequenceAt(i).getName().equals(name))
351 matches.addElement(getSequenceAt(i));
356 SequenceI[] result = new SequenceI[matches.size()];
357 for (i = 0; i < result.length; i++)
359 result[i] = (SequenceI) matches.elementAt(i);
367 public int findIndex(SequenceI s)
371 while (i < sequences.size())
373 if (s == getSequenceAt(i))
387 * @return DOCUMENT ME!
389 public int getHeight()
391 return sequences.size();
397 * @return DOCUMENT ME!
399 public int getWidth()
403 for (int i = 0; i < sequences.size(); i++)
405 if (getSequenceAt(i).getLength() > maxLength)
407 maxLength = getSequenceAt(i).getLength();
417 * @param gc DOCUMENT ME!
419 public void setGapCharacter(char gc)
423 for (int i = 0; i < sequences.size(); i++)
425 Sequence seq = (Sequence) sequences.elementAt(i);
426 seq.setSequence(seq.getSequenceAsString()
437 * @return DOCUMENT ME!
439 public char getGapCharacter()
447 * @return DOCUMENT ME!
449 public boolean isAligned()
451 int width = getWidth();
453 for (int i = 0; i < sequences.size(); i++)
455 if (getSequenceAt(i).getLength() != width)
464 * @see jalview.datamodel.AlignmentI#deleteAnnotation(jalview.datamodel.AlignmentAnnotation)
466 public boolean deleteAnnotation(AlignmentAnnotation aa)
470 if (annotations != null)
472 aSize = annotations.length;
480 AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize - 1];
485 for (int i = 0; i < aSize; i++)
487 if (annotations[i] == aa)
492 if (tIndex<temp.length)
493 temp[tIndex++] = annotations[i];
499 if(aa.sequenceRef!=null)
500 aa.sequenceRef.removeAlignmentAnnotation(aa);
508 * @param aa DOCUMENT ME!
510 public void addAnnotation(AlignmentAnnotation aa)
513 if (annotations != null)
515 aSize = annotations.length + 1;
518 AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize];
520 temp[aSize - 1] = aa;
526 for (i = 0; i < (aSize - 1); i++)
528 temp[i] = annotations[i];
535 public void setAnnotationIndex(AlignmentAnnotation aa, int index)
537 if (aa == null || annotations == null || annotations.length - 1 < index)
542 int aSize = annotations.length;
543 AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize];
547 for (int i = 0; i < aSize; i++)
556 temp[i] = annotations[i];
560 temp[i] = annotations[i - 1];
570 * @return DOCUMENT ME!
572 public AlignmentAnnotation[] getAlignmentAnnotation()
577 public void setNucleotide(boolean b)
589 public boolean isNucleotide()
591 if (type == NUCLEOTIDE)
601 public void setDataset(Alignment data)
603 if (dataset == null && data == null)
605 // Create a new dataset for this alignment.
606 // Can only be done once, if dataset is not null
607 // This will not be performed
608 Sequence[] seqs = new Sequence[getHeight()];
609 SequenceI currentSeq;
610 for (int i = 0; i < getHeight(); i++)
612 currentSeq = getSequenceAt(i);
613 if (currentSeq.getDatasetSequence() != null)
615 seqs[i] = (Sequence) currentSeq.getDatasetSequence();
619 seqs[i] = new Sequence(currentSeq.getName(),
620 AlignSeq.extractGaps(
621 jalview.util.Comparison.GapChars,
622 currentSeq.getSequenceAsString()
624 currentSeq.getStart(),
625 currentSeq.getEnd());
626 seqs[i].sequenceFeatures = currentSeq.getSequenceFeatures();
627 seqs[i].setDescription(currentSeq.getDescription());
628 getSequenceAt(i).setSequenceFeatures(null);
629 getSequenceAt(i).setDatasetSequence(seqs[i]);
633 dataset = new Alignment(seqs);
635 else if (dataset == null && data != null)
641 public Alignment getDataset()
646 public boolean padGaps()
648 boolean modified = false;
650 //Remove excess gaps from the end of alignment
654 for (int i = 0; i < sequences.size(); i++)
656 current = getSequenceAt(i);
657 for (int j = current.getLength(); j > maxLength; j--)
659 if (j > maxLength && !jalview.util.Comparison.isGap(
660 current.getCharAt(j)))
671 for (int i = 0; i < sequences.size();
674 current = getSequenceAt(i);
675 cLength = current.getLength();
677 if (cLength < maxLength)
679 current.insertCharAt(cLength,
680 maxLength - cLength, gapCharacter);
683 else if (current.getLength() > maxLength)
685 current.deleteChars(maxLength, current.getLength());
691 public HiddenSequences getHiddenSequences()
693 return hiddenSequences;
696 public CigarArray getCompactAlignment()
698 SeqCigar alseqs[] = new SeqCigar[sequences.size()];
699 for (int i = 0; i < sequences.size(); i++)
701 alseqs[i] = new SeqCigar( (SequenceI) sequences.elementAt(i));
703 CigarArray cal = new CigarArray(alseqs);
704 cal.addOperation(CigarArray.M, getWidth());
708 public void setProperty(Object key, Object value)
710 if(alignmentProperties==null)
711 alignmentProperties = new Hashtable();
713 alignmentProperties.put(key,value);
716 public Object getProperty(Object key)
718 if(alignmentProperties!=null)
719 return alignmentProperties.get(key);
724 public Hashtable getProperties()
726 return alignmentProperties;