X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FAlignment.java;h=afe70328877239ab9a727083384405a44644bb14;hb=73ffad785a317d4014bc448ea4d8a7303e8a4350;hp=f36872ee11724358c02b5a46b5ad4372271073a5;hpb=d537c0ee8ef1907b348237645765671674f8f304;p=jalview.git diff --git a/src/jalview/datamodel/Alignment.java b/src/jalview/datamodel/Alignment.java index f36872e..afe7032 100755 --- a/src/jalview/datamodel/Alignment.java +++ b/src/jalview/datamodel/Alignment.java @@ -1,17 +1,17 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer - * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle - * + * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1) + * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA @@ -22,17 +22,27 @@ import java.util.*; import jalview.analysis.*; -/** Data structure to hold and manipulate a multiple sequence alignment +/** + * Data structure to hold and manipulate a multiple sequence alignment */ -public class Alignment - implements AlignmentI +/** + * @author JimP + * + */ +public class Alignment implements AlignmentI { protected Alignment dataset; + protected Vector sequences; + protected Vector groups = new Vector(); + protected char gapCharacter = '-'; + protected int type = NUCLEOTIDE; + public static final int PROTEIN = 0; + public static final int NUCLEOTIDE = 1; /** DOCUMENT ME!! */ @@ -64,8 +74,9 @@ public class Alignment } - /** Make an alignment from an array of Sequences. - * + /** + * Make an alignment from an array of Sequences. + * * @param sequences */ public Alignment(SequenceI[] seqs) @@ -75,20 +86,25 @@ public class Alignment /** * Make a new alignment from an array of SeqCigars - * @param seqs SeqCigar[] + * + * @param seqs + * SeqCigar[] */ public Alignment(SeqCigar[] alseqs) { - SequenceI[] seqs = SeqCigar.createAlignmentSequences(alseqs, gapCharacter, - new ColumnSelection(), null); + SequenceI[] seqs = SeqCigar.createAlignmentSequences(alseqs, + gapCharacter, new ColumnSelection(), null); initAlignment(seqs); } /** - * Make a new alignment from an CigarArray - * JBPNote - can only do this when compactAlignment does not contain hidden regions. - * JBPNote - must also check that compactAlignment resolves to a set of SeqCigars - or construct them appropriately. - * @param compactAlignment CigarArray + * Make a new alignment from an CigarArray JBPNote - can only do this when + * compactAlignment does not contain hidden regions. JBPNote - must also check + * that compactAlignment resolves to a set of SeqCigars - or construct them + * appropriately. + * + * @param compactAlignment + * CigarArray */ public static AlignmentI createAlignment(CigarArray compactAlignment) { @@ -98,7 +114,7 @@ public class Alignment /** * DOCUMENT ME! - * + * * @return DOCUMENT ME! */ public Vector getSequences() @@ -108,7 +124,7 @@ public class Alignment public SequenceI[] getSequencesArray() { - if (sequences==null) + if (sequences == null) return null; SequenceI[] reply = new SequenceI[sequences.size()]; for (int i = 0; i < sequences.size(); i++) @@ -120,9 +136,10 @@ public class Alignment /** * DOCUMENT ME! - * - * @param i DOCUMENT ME! - * + * + * @param i + * DOCUMENT ME! + * * @return DOCUMENT ME! */ public SequenceI getSequenceAt(int i) @@ -135,8 +152,9 @@ public class Alignment return null; } - /** Adds a sequence to the alignment. Recalculates maxLength and size. - * + /** + * Adds a sequence to the alignment. Recalculates maxLength and size. + * * @param snew */ public void addSequence(SequenceI snew) @@ -156,17 +174,22 @@ public class Alignment snew = adding; } } - if (sequences==null) { - initAlignment(new SequenceI[] { snew }); - } else { + if (sequences == null) + { + initAlignment(new SequenceI[] + { snew }); + } + else + { sequences.addElement(snew); } - if (hiddenSequences!=null) + if (hiddenSequences != null) hiddenSequences.adjustHeightSequenceAdded(); } - /** Adds a sequence to the alignment. Recalculates maxLength and size. - * + /** + * Adds a sequence to the alignment. Recalculates maxLength and size. + * * @param snew */ public void setSequenceAt(int i, SequenceI snew) @@ -179,7 +202,7 @@ public class Alignment /** * DOCUMENT ME! - * + * * @return DOCUMENT ME! */ public Vector getGroups() @@ -189,7 +212,7 @@ public class Alignment public void finalize() { - if(getDataset()!=null) + if (getDataset() != null) getDataset().removeAlignmentRef(); dataset = null; @@ -200,11 +223,12 @@ public class Alignment } /** - * decrement the alignmentRefs counter by one and call finalize if it goes to zero. + * decrement the alignmentRefs counter by one and call finalize if it goes to + * zero. */ private void removeAlignmentRef() { - if (--alignmentRefs==0) + if (--alignmentRefs == 0) { finalize(); } @@ -212,8 +236,9 @@ public class Alignment /** * DOCUMENT ME! - * - * @param s DOCUMENT ME! + * + * @param s + * DOCUMENT ME! */ public void deleteSequence(SequenceI s) { @@ -222,8 +247,9 @@ public class Alignment /** * DOCUMENT ME! - * - * @param i DOCUMENT ME! + * + * @param i + * DOCUMENT ME! */ public void deleteSequence(int i) { @@ -252,9 +278,10 @@ public class Alignment /** * DOCUMENT ME! - * - * @param s DOCUMENT ME! - * + * + * @param s + * DOCUMENT ME! + * * @return DOCUMENT ME! */ public SequenceGroup[] findAllGroups(SequenceI s) @@ -329,6 +356,14 @@ public class Alignment { if (groups.contains(g)) { + if (annotations!=null && annotations.length>0) + { + if (g.hasAnnotationRows()) + { // remove any annotation references. + deleteAnnotation(g.getConsensus());// todo - create=false flag so we don't create another object unnecessarily + deleteAnnotation(g.getConservationRow()); + } + } groups.removeElement(g); } } @@ -336,11 +371,55 @@ public class Alignment /** */ public SequenceI findName(String name) { - int i = 0; + return findName(name, false); + } + + /* + * (non-Javadoc) + * + * @see jalview.datamodel.AlignmentI#findName(java.lang.String, boolean) + */ + public SequenceI findName(String token, boolean b) + { + return findName(null, token, b); + } + + /* + * (non-Javadoc) + * + * @see jalview.datamodel.AlignmentI#findName(SequenceI, java.lang.String, + * boolean) + */ + public SequenceI findName(SequenceI startAfter, String token, boolean b) + { + int i = 0; + SequenceI sq = null; + String sqname = null; + if (startAfter != null) + { + // try to find the sequence in the alignment + boolean matched = false; + while (i < sequences.size()) + { + if (getSequenceAt(i++) == startAfter) + { + matched = true; + break; + } + } + if (!matched) + { + i = 0; + } + } while (i < sequences.size()) { - if (getSequenceAt(i).getName().equals(name)) + sq = getSequenceAt(i); + sqname = sq.getName(); + if (sqname.equals(token) // exact match + || (b && // allow imperfect matches - case varies + (sqname.equalsIgnoreCase(token)))) { return getSequenceAt(i); } @@ -375,7 +454,11 @@ public class Alignment } - /** */ + /* + * (non-Javadoc) + * + * @see jalview.datamodel.AlignmentI#findIndex(jalview.datamodel.SequenceI) + */ public int findIndex(SequenceI s) { int i = 0; @@ -393,9 +476,29 @@ public class Alignment return -1; } + /* + * (non-Javadoc) + * + * @see jalview.datamodel.AlignmentI#findIndex(jalview.datamodel.SearchResults) + */ + public int findIndex(SearchResults results) + { + int i = 0; + + while (i < sequences.size()) + { + if (results.involvesSequence(getSequenceAt(i))) + { + return i; + } + i++; + } + return -1; + } + /** * DOCUMENT ME! - * + * * @return DOCUMENT ME! */ public int getHeight() @@ -405,7 +508,7 @@ public class Alignment /** * DOCUMENT ME! - * + * * @return DOCUMENT ME! */ public int getWidth() @@ -425,8 +528,9 @@ public class Alignment /** * DOCUMENT ME! - * - * @param gc DOCUMENT ME! + * + * @param gc + * DOCUMENT ME! */ public void setGapCharacter(char gc) { @@ -435,17 +539,14 @@ public class Alignment for (int i = 0; i < sequences.size(); i++) { Sequence seq = (Sequence) sequences.elementAt(i); - seq.setSequence(seq.getSequenceAsString() - .replace('.', gc) - .replace('-', gc) - .replace(' ', gc) - ); + seq.setSequence(seq.getSequenceAsString().replace('.', gc).replace( + '-', gc).replace(' ', gc)); } } /** * DOCUMENT ME! - * + * * @return DOCUMENT ME! */ public char getGapCharacter() @@ -455,7 +556,7 @@ public class Alignment /** * DOCUMENT ME! - * + * * @return DOCUMENT ME! */ public boolean isAligned() @@ -472,7 +573,10 @@ public class Alignment return true; } - /* (non-Javadoc) + + /* + * (non-Javadoc) + * * @see jalview.datamodel.AlignmentI#deleteAnnotation(jalview.datamodel.AlignmentAnnotation) */ public boolean deleteAnnotation(AlignmentAnnotation aa) @@ -491,36 +595,42 @@ public class Alignment AlignmentAnnotation[] temp = new AlignmentAnnotation[aSize - 1]; - boolean swap=false; + boolean swap = false; int tIndex = 0; for (int i = 0; i < aSize; i++) { if (annotations[i] == aa) { - swap=true; + swap = true; continue; } - if (tIndex=aSize) { + temp[aSize - 1] = aa; + } else { + temp[pos] = aa; + } if (aSize > 1) { - for (i = 0; i < (aSize - 1); i++) + int p=0; + for (i = 0; i < (aSize-1); i++,p++) { - temp[i] = annotations[i]; + if (p==pos) + { + p++; + } + if (p maxLength; j--) { - if (j > maxLength && !jalview.util.Comparison.isGap( - current.getCharAt(j))) + if (j > maxLength + && !jalview.util.Comparison.isGap(current.getCharAt(j))) { maxLength = j; break; @@ -682,16 +802,14 @@ public class Alignment maxLength++; int cLength; - for (int i = 0; i < sequences.size(); - i++) + for (int i = 0; i < sequences.size(); i++) { current = getSequenceAt(i); cLength = current.getLength(); if (cLength < maxLength) { - current.insertCharAt(cLength, - maxLength - cLength, gapCharacter); + current.insertCharAt(cLength, maxLength - cLength, gapCharacter); modified = true; } else if (current.getLength() > maxLength) @@ -701,6 +819,98 @@ public class Alignment } return modified; } + /** + * Justify the sequences to the left or right by deleting and inserting gaps before the initial residue or after the terminal residue + * @param right true if alignment padded to right, false to justify to left + * @return true if alignment was changed + */ + public boolean justify(boolean right) + { + boolean modified = false; + + // Remove excess gaps from the end of alignment + int maxLength = -1; + int ends[] = new int[sequences.size()*2]; + SequenceI current; + for (int i = 0; i < sequences.size(); i++) + { + current = getSequenceAt(i); + // This should really be a sequence method + ends[i*2] = current.findIndex(current.getStart()); + ends[i*2+1] = current.findIndex(current.getStart()+current.getLength()); + boolean hitres=false; + for (int j = 0,rs=0,ssiz=current.getLength(); jmaxLength) + { + maxLength = j-ends[i*2]; + } + } + } + } + } + + maxLength++; + // now edit the flanking gaps to justify to either left or right + int cLength,extent,diff; + for (int i = 0; i < sequences.size(); i++) + { + current = getSequenceAt(i); + + cLength = 1+ends[i*2+1]-ends[i*2]; + diff = maxLength-cLength; // number of gaps to indent + extent = current.getLength(); + if (right) + { + // right justify + if (extent>ends[i*2+1]) + { + current.deleteChars(ends[i*2+1]+1, extent); + modified = true; + } + if (ends[i*2]>diff) + { + current.deleteChars(0, ends[i*2]-diff); + modified = true; + } else { + if (ends[i*2]0) + { + current.deleteChars(0, ends[i*2]); + modified = true; + ends[i*2+1]-=ends[i*2]; + extent-=ends[i*2]; + } + if (extent>maxLength) + { + current.deleteChars(maxLength+1, extent); + modified = true; + } else { + if (extent