X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fanalysis%2FAlignmentSorter.java;h=24f2ddfa2f62f7596e5b33b2db4f3b8d6cd3cfe2;hb=3f9c1d052c8fe2e92ae0d7a1c3088ccb82c58ba5;hp=bdd6bce55604291d6ae4c69d5b3f9dd8f1999767;hpb=dc6d9b88b36c704faa61bcd3ed29a9e2f510bc83;p=jalview.git diff --git a/src/jalview/analysis/AlignmentSorter.java b/src/jalview/analysis/AlignmentSorter.java index bdd6bce..24f2ddf 100755 --- a/src/jalview/analysis/AlignmentSorter.java +++ b/src/jalview/analysis/AlignmentSorter.java @@ -1,6 +1,6 @@ /* * Jalview - A Sequence Alignment Editor and Viewer -* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle +* Copyright (C) 2006 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 @@ -20,8 +20,6 @@ package jalview.analysis; import jalview.datamodel.*; -import jalview.io.*; - import jalview.util.*; import java.util.*; @@ -29,8 +27,8 @@ import java.util.*; /** Data structure to hold and manipulate a multiple sequence alignment */ -public class AlignmentSorter { - /** */ +public class AlignmentSorter +{ static boolean sortIdAscending = true; static int lastGroupHash = 0; static boolean sortGroupAscending = true; @@ -45,14 +43,17 @@ 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]; - for (int i = 0; i < nSeq; i++) { - scores[i] = Comparison.PID(align.getSequenceAt(i), s); + for (int i = 0; i < nSeq; i++) + { + scores[i] = Comparison.PID(align.getSequenceAt(i).getSequenceAsString(), + s.getSequenceAsString()); seqs[i] = align.getSequenceAt(i); } @@ -61,129 +62,212 @@ public class AlignmentSorter { 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) { + if ((nSeq % 2) == 0) + { len = nSeq / 2; - } else { + } + else + { len = (nSeq + 1) / 2; } // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work - for (int i = 0; i < len; i++) { + 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); } } - private static void setOrder(AlignmentI align, Vector tmp) { + /** + * 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) { - + /** + * 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(); + for (int i = 0; i < seqs.length; i++) { - algn.setElementAt(seqs[i], 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)); } + + + + } - 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]; - for (int i = 0; i < nSeq; i++) { + for (int i = 0; i < nSeq; i++) + { ids[i] = align.getSequenceAt(i).getName(); seqs[i] = align.getSequenceAt(i); } QuickSort.sort(ids, seqs); - if (sortIdAscending) { + if (sortIdAscending) + { setReverseOrder(align, seqs); - } else { + } + else + { setOrder(align, seqs); } sortIdAscending = !sortIdAscending; } - public static void sortByGroup(AlignmentI align) { - //MAINTAINS ORIGNAL SEQUENCE ORDER, - //ORDERS BY GROUP SIZE - + /** + * 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) { + if (groups.hashCode() != lastGroupHash) + { sortGroupAscending = true; lastGroupHash = groups.hashCode(); - } else { + } + else + { sortGroupAscending = !sortGroupAscending; } //SORTS GROUPS BY SIZE ////////////////////// - for(int i=0; i sg2.getSize()) - { - groups.insertElementAt(sg, j); - break; - } - } - - if (!groups.contains(sg)) - { - groups.addElement(sg); - } + SequenceGroup sg = (SequenceGroup) align.getGroups().elementAt(i); + + for (int j = 0; j < groups.size(); j++) + { + SequenceGroup sg2 = (SequenceGroup) groups.elementAt(j); + + if (sg.getSize(false) > sg2.getSize(false)) + { + groups.insertElementAt(sg, j); + + break; + } + } + + if (!groups.contains(sg)) + { + groups.addElement(sg); + } } //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); + SequenceI[] orderedseqs = sg.getSequencesInOrder(align); + for (int j = 0; j < orderedseqs.length; j++) { seqs.addElement(orderedseqs[j]); } } - if (sortGroupAscending) { + if (sortGroupAscending) + { setOrder(align, seqs); - } else { + } + 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++) { + 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; boolean[] tmask = new boolean[mask.size()]; @@ -191,8 +275,8 @@ public class AlignmentSorter { for (i = 0; i < mask.size(); i++) tmask[i] = true; - for (i = 0; i < tmp.size(); i++) { - + for (i = 0; i < tmp.size(); i++) + { Object sq = tmp.elementAt(i); if (mask.contains(sq) && tmask[mask.indexOf(sq)]) @@ -203,47 +287,73 @@ public class AlignmentSorter { } for (i = 0; i < tmask.length; i++) - if (tmask[i]) { + if (tmask[i]) + { seqs.addElement(mask.elementAt(i)); } return vectorToArray(seqs); } - public static void sortBy(AlignmentI align, AlignmentOrder order) { + /** + * Sorts by a given AlignmentOrder object + * + * @param align Alignment to order + * @param order specified order for alignment + */ + public static void sortBy(AlignmentI align, AlignmentOrder order) + { // Get an ordered vector of sequences which may also be present in align Vector tmp = order.getOrder(); - if (lastOrder == order) { + if (lastOrder == order) + { sortOrderAscending = !sortOrderAscending; - } else { + } + else + { sortOrderAscending = true; } - if (sortOrderAscending) { + if (sortOrderAscending) + { setOrder(align, tmp); - } else { + } + else + { setReverseOrder(align, vectorSubsetToArray(tmp, align.getSequences())); } } - public static Vector getOrderByTree(AlignmentI align, NJTree tree) { + /** + * DOCUMENT ME! + * + * @param align alignment to order + * @param tree tree which has + * + * @return DOCUMENT ME! + */ + private static Vector getOrderByTree(AlignmentI align, NJTree tree) + { int nSeq = align.getHeight(); Vector tmp = new Vector(); tmp = _sortByTree(tree.getTopNode(), tmp, align.getSequences()); - if (tmp.size() != nSeq) { + if (tmp.size() != nSeq) + { // TODO: JBPNote - decide if this is always an error // (eg. not when a tree is associated to another alignment which has more // sequences) - if (tmp.size() < nSeq) { + if (tmp.size() < nSeq) + { addStrays(align, tmp); } - if (tmp.size() != nSeq) { + if (tmp.size() != nSeq) + { System.err.println("ERROR: tmp.size()=" + tmp.size() + " != nseq=" + nSeq + " in getOrderByTree"); } @@ -252,60 +362,100 @@ public class AlignmentSorter { return tmp; } - public static void sortByTree(AlignmentI align, NJTree tree) { + /** + * Sorts the alignment by a given tree + * + * @param align alignment to order + * @param tree tree which has + */ + public static void sortByTree(AlignmentI align, NJTree tree) + { Vector tmp = getOrderByTree(align, tree); // tmp should properly permute align with tree. - if (lastTree != tree) { + if (lastTree != tree) + { sortTreeAscending = true; lastTree = tree; - } else { + } + else + { sortTreeAscending = !sortTreeAscending; } - if (sortTreeAscending) { + if (sortTreeAscending) + { setOrder(align, tmp); - } else { + } + else + { setReverseOrder(align, vectorSubsetToArray(tmp, align.getSequences())); } } - private static void addStrays(AlignmentI align, Vector seqs) { + /** + * DOCUMENT ME! + * + * @param align DOCUMENT ME! + * @param seqs DOCUMENT ME! + */ + private static void addStrays(AlignmentI align, Vector seqs) + { int nSeq = align.getHeight(); - for (int i = 0; i < nSeq; i++) { - if (!seqs.contains(align.getSequenceAt(i))) { + for (int i = 0; i < nSeq; i++) + { + if (!seqs.contains(align.getSequenceAt(i))) + { seqs.addElement(align.getSequenceAt(i)); } } - if (nSeq != seqs.size()) { + if (nSeq != seqs.size()) + { System.err.println( "ERROR: Size still not right even after addStrays"); } } - public static Vector _sortByTree(SequenceNode node, Vector tmp, - Vector seqset) { - if (node == null) { + /** + * DOCUMENT ME! + * + * @param node DOCUMENT ME! + * @param tmp DOCUMENT ME! + * @param seqset DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + private static Vector _sortByTree(SequenceNode node, Vector tmp, + Vector seqset) + { + if (node == null) + { return tmp; } SequenceNode left = (SequenceNode) node.left(); SequenceNode right = (SequenceNode) node.right(); - if ((left == null) && (right == null)) { - if (!node.isPlaceholder() && (node.element() != null)) { - if (node.element() instanceof SequenceI) { - if (!tmp.contains(node.element())) { + if ((left == null) && (right == null)) + { + if (!node.isPlaceholder() && (node.element() != null)) + { + if (node.element() instanceof SequenceI) + { + if (!tmp.contains(node.element())) + { tmp.addElement((SequenceI) node.element()); } } } return tmp; - } else { + } + else + { _sortByTree(left, tmp, seqset); _sortByTree(right, tmp, seqset); } @@ -321,7 +471,8 @@ public class AlignmentSorter { * recover the order of sequences given by the safe numbering scheme introducd * SeqsetUtils.uniquify. */ - public static void recoverOrder(SequenceI[] alignment) { + public static void recoverOrder(SequenceI[] alignment) + { float[] ids = new float[alignment.length]; for (int i = 0; i < alignment.length; i++)