X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fanalysis%2FAlignmentSorter.java;h=ea8d4e58ae553a30a08b5120eba51d40ef6bd9cf;hb=1a0f6886ffdb431de180af2089db4910a1dfb564;hp=8274768ef55e563c276380f610eb12e773949e26;hpb=636c4829ba51f11e71e56c1470fb3ad73eeb81c3;p=jalview.git diff --git a/src/jalview/analysis/AlignmentSorter.java b/src/jalview/analysis/AlignmentSorter.java index 8274768..ea8d4e5 100755 --- a/src/jalview/analysis/AlignmentSorter.java +++ b/src/jalview/analysis/AlignmentSorter.java @@ -1,48 +1,39 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer + * Copyright (C) 2007 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 + */ package jalview.analysis; +import java.util.*; + import jalview.datamodel.*; import jalview.util.*; -import jalview.io.*; - -import java.util.*; /** Data structure to hold and manipulate a multiple sequence alignment */ -public class AlignmentSorter { - - private AlignmentSorter() { - try - { - jbInit(); - } - catch (Exception ex) - { - ex.printStackTrace(); - } - } - - public static void sortGroups(AlignmentI align) { - Vector groups = align.getGroups(); - int nGroup = groups.size(); - - float[] arr = new float [nGroup]; - Object[] s = new Object[nGroup]; - - for (int i=0; i < nGroup; i++) { - arr[i] = ((SequenceGroup)groups.elementAt(i)).getSize(); - s[i] = groups.elementAt(i); - } - - QuickSort.sort(arr,s); - - Vector newg = new Vector(nGroup); - - for (int i=nGroup-1; i >= 0; i--) { - newg.addElement(s[i]); - } - - // align.setGroups(newg); - } +public class AlignmentSorter +{ + static boolean sortIdAscending = true; + static int lastGroupHash = 0; + static boolean sortGroupAscending = true; + static AlignmentOrder lastOrder = null; + static boolean sortOrderAscending = true; + static NJTree lastTree = null; + static boolean sortTreeAscending = true; /** * Sort by Percentage Identity @@ -50,163 +41,302 @@ public class AlignmentSorter { * @param align AlignmentI * @param s SequenceI */ - public static void sortByPID(AlignmentI align, SequenceI s) { + public static void sortByPID(AlignmentI align, SequenceI s) + { int nSeq = align.getHeight(); - float scores[] = new float[nSeq]; - SequenceI seqs[] = new SequenceI[nSeq]; + float[] scores = new float[nSeq]; + SequenceI[] seqs = new SequenceI[nSeq]; - for (int i = 0; i < nSeq; i++) { - scores[i] = Comparison.PID(align.getSequenceAt(i),s); - seqs[i] = align.getSequenceAt(i); + for (int i = 0; i < nSeq; i++) + { + scores[i] = Comparison.PID(align.getSequenceAt(i).getSequenceAsString(), + s.getSequenceAsString()); + seqs[i] = align.getSequenceAt(i); } - QuickSort.sort(scores,0,scores.length-1,seqs); + QuickSort.sort(scores, 0, scores.length - 1, seqs); - setReverseOrder(align,seqs); + setReverseOrder(align, seqs); } - private static void setReverseOrder(AlignmentI align, SequenceI [] seqs) { + /** + * Reverse the order of the sort + * + * @param align DOCUMENT ME! + * @param seqs DOCUMENT ME! + */ + private static void setReverseOrder(AlignmentI align, SequenceI[] seqs) + { int nSeq = seqs.length; int len = 0; - if (nSeq%2 == 0) { - len = nSeq/2; - } else { - len = (nSeq+1)/2; + + if ( (nSeq % 2) == 0) + { + len = nSeq / 2; + } + else + { + len = (nSeq + 1) / 2; } -// NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work - for (int i = 0; i < len; i++) { + // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work + for (int i = 0; i < len; i++) + { //SequenceI tmp = seqs[i]; - align.getSequences().setElementAt(seqs[nSeq-i-1],i); - align.getSequences().setElementAt(seqs[i],nSeq-i-1); + align.getSequences().setElementAt(seqs[nSeq - i - 1], i); + align.getSequences().setElementAt(seqs[i], nSeq - i - 1); } } - private static void setOrder(AlignmentI align, Vector tmp) { - setOrder(align,vectorSubsetToArray(tmp, align.getSequences())); + /** + * Sets the Alignment object with the given sequences + * + * @param align Alignment object to be updated + * @param tmp sequences as a vector + */ + private static void setOrder(AlignmentI align, Vector tmp) + { + setOrder(align, vectorSubsetToArray(tmp, align.getSequences())); } - private static void setOrder(AlignmentI align, SequenceI [] seqs) { - // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work + /** + * Sets the Alignment object with the given sequences + * + * @param align DOCUMENT ME! + * @param seqs sequences as an array + */ + public static void setOrder(AlignmentI align, SequenceI[] seqs) + { + // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work + Vector algn = align.getSequences(); + Vector tmp = new Vector(); - Vector algn = align.getSequences(); + for (int i = 0; i < seqs.length; i++) + { + if (algn.contains(seqs[i])) + { + tmp.addElement(seqs[i]); + } + } + + algn.removeAllElements(); + //User may have hidden seqs, then clicked undo or redo + for (int i = 0; i < tmp.size(); i++) + { + algn.addElement(tmp.elementAt(i)); + } - for (int i = 0, p = 0; i < seqs.length; i++) - algn.setElementAt(seqs[i], p++); } - /** */ - static boolean sortIdAscending = true; - public static void sortByID(AlignmentI align) { + + /** + * Sorts by ID. Numbers are sorted before letters. + * + * @param align The alignment object to sort + */ + public static void sortByID(AlignmentI align) + { int nSeq = align.getHeight(); - String ids[] = new String[nSeq]; - SequenceI seqs[] = new SequenceI[nSeq]; + String[] ids = new String[nSeq]; + SequenceI[] seqs = new SequenceI[nSeq]; - for (int i = 0; i < nSeq; i++) { - ids[i] = align.getSequenceAt(i).getName(); + for (int i = 0; i < nSeq; i++) + { + ids[i] = align.getSequenceAt(i).getName(); seqs[i] = align.getSequenceAt(i); } - QuickSort.sort(ids,seqs); + QuickSort.sort(ids, seqs); - if(sortIdAscending) - setReverseOrder(align,seqs); + if (sortIdAscending) + { + setReverseOrder(align, seqs); + } else + { setOrder(align, seqs); + } sortIdAscending = !sortIdAscending; } - static int lastGroupHash = 0; - static boolean sortGroupAscending = true; - public static void sortByGroup(AlignmentI align) { - int nSeq = align.getHeight(); - Vector groups = align.getGroups(); - if (groups.hashCode()!=lastGroupHash) { - sortGroupAscending=true; + /** + * Sorts the alignment by size of group. + *
Maintains the order of sequences in each group + * by order in given alignment object. + * + * @param align sorts the given alignment object by group + */ + public static void sortByGroup(AlignmentI align) + { + //MAINTAINS ORIGNAL SEQUENCE ORDER, + //ORDERS BY GROUP SIZE + Vector groups = new Vector(); + + if (groups.hashCode() != lastGroupHash) + { + sortGroupAscending = true; lastGroupHash = groups.hashCode(); - } else - sortGroupAscending = ! sortGroupAscending; + } + else + { + sortGroupAscending = !sortGroupAscending; + } - Vector seqs = new Vector(); + //SORTS GROUPS BY SIZE + ////////////////////// + for (int i = 0; i < align.getGroups().size(); i++) + { + SequenceGroup sg = (SequenceGroup) align.getGroups().elementAt(i); - for (int i=0; i < groups.size(); i++) { - SequenceGroup sg = (SequenceGroup)groups.elementAt(i); + for (int j = 0; j < groups.size(); j++) + { + SequenceGroup sg2 = (SequenceGroup) groups.elementAt(j); - for (int j = 0; j < sg.getSize(); j++) { - seqs.addElement(sg.getSequenceAt(j)); + if (sg.getSize() > sg2.getSize()) + { + groups.insertElementAt(sg, j); + + break; + } + } + + if (!groups.contains(sg)) + { + groups.addElement(sg); } } - // Deletions can happen so this check may fail - /* - if (seqs.size() != nSeq) { - System.err.println("ERROR: tmp.size() != nseq in sortByGroups"); - if (seqs.size() < nSeq) { - addStrays(align,seqs); + //NOW ADD SEQUENCES MAINTAINING ALIGNMENT ORDER + /////////////////////////////////////////////// + Vector seqs = new Vector(); + + for (int i = 0; i < groups.size(); i++) + { + SequenceGroup sg = (SequenceGroup) groups.elementAt(i); + SequenceI[] orderedseqs = sg.getSequencesInOrder(align); + + for (int j = 0; j < orderedseqs.length; j++) + { + seqs.addElement(orderedseqs[j]); } } -*/ - if(sortGroupAscending) - setOrder(align,seqs); - else - setReverseOrder( align, vectorSubsetToArray(seqs, align.getSequences())); + if (sortGroupAscending) + { + setOrder(align, seqs); + } + else + { + setReverseOrder(align, + vectorSubsetToArray(seqs, align.getSequences())); + } } - private static SequenceI [] vectorToArray(Vector tmp) { + /** + * Converts Vector to array. + * java 1.18 does not have Vector.toArray() + * + * @param tmp Vector of SequenceI objects + * + * @return array of Sequence[] + */ + private static SequenceI[] vectorToArray(Vector tmp) + { SequenceI[] seqs = new SequenceI[tmp.size()]; - for (int i=0; i < tmp.size(); i++) { - seqs[i] = (SequenceI)tmp.elementAt(i); + for (int i = 0; i < tmp.size(); i++) + { + seqs[i] = (SequenceI) tmp.elementAt(i); } + return seqs; } - private static SequenceI [] vectorSubsetToArray(Vector tmp, Vector mask) { + /** + * DOCUMENT ME! + * + * @param tmp DOCUMENT ME! + * @param mask DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + private static SequenceI[] vectorSubsetToArray(Vector tmp, Vector mask) + { Vector seqs = new Vector(); - int i,m, p; - boolean[] tmask = new boolean[m=mask.size()]; - for (i=0; i