64682c1f2433e0f2ba9fec3587dee3e5b9eaccd9
[jalview.git] / src / jalview / analysis / AlignmentSorter.java
1 package jalview.analysis;\r
2 \r
3 import jalview.datamodel.*;\r
4 import jalview.util.*;\r
5 import jalview.io.*;\r
6 \r
7 import java.util.*;\r
8 \r
9 /** Data structure to hold and manipulate a multiple sequence alignment\r
10  */\r
11 public class AlignmentSorter {\r
12 \r
13   private AlignmentSorter() {\r
14   }\r
15 \r
16   public static void sortGroups(AlignmentI align) {\r
17     Vector groups = align.getGroups();\r
18     int    nGroup = groups.size();\r
19 \r
20     float[]  arr = new float [nGroup];\r
21     Object[] s   = new Object[nGroup];\r
22 \r
23     for (int i=0; i < nGroup; i++) {\r
24       arr[i] = ((SequenceGroup)groups.elementAt(i)).getSize();\r
25       s[i]   = groups.elementAt(i);\r
26     }\r
27 \r
28     QuickSort.sort(arr,s);\r
29 \r
30     Vector newg = new Vector(nGroup);\r
31 \r
32     for (int i=nGroup-1; i >= 0; i--) {\r
33       newg.addElement(s[i]);\r
34     }\r
35 \r
36     //    align.setGroups(newg);\r
37   }\r
38 \r
39   /**    */\r
40   public static void sortByPID(AlignmentI align, SequenceI s) {\r
41     int nSeq = align.getHeight();\r
42 \r
43     float     scores[] = new float[nSeq];\r
44     SequenceI seqs[]   = new SequenceI[nSeq];\r
45 \r
46     for (int i = 0; i < nSeq; i++) {\r
47       scores[i] = Comparison.compare(align.getSequenceAt(i),s);\r
48       seqs[i]   = align.getSequenceAt(i);\r
49     }\r
50 \r
51     QuickSort.sort(scores,0,scores.length-1,seqs);\r
52 \r
53    setReverseOrder(align,seqs);\r
54   }\r
55 \r
56   private static void setReverseOrder(AlignmentI align, SequenceI [] seqs) {\r
57     int nSeq = seqs.length;\r
58 \r
59     int len = 0;\r
60     if (nSeq%2 == 0) {\r
61       len = nSeq/2;\r
62     } else {\r
63       len = (nSeq+1)/2;\r
64     }\r
65 \r
66 // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work\r
67     for (int i = 0; i < len; i++) {\r
68       //SequenceI tmp = seqs[i];\r
69       align.getSequences().setElementAt(seqs[nSeq-i-1],i);\r
70       align.getSequences().setElementAt(seqs[i],nSeq-i-1);\r
71     }\r
72   }\r
73 \r
74   private static void setOrder(AlignmentI align, Vector tmp) {\r
75     setOrder(align,vectorToArray(tmp));\r
76   }\r
77 \r
78   private static void setOrder(AlignmentI align, SequenceI [] seqs) {\r
79 // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work\r
80     for (int i = 0; i < seqs.length; i++) {\r
81       align.getSequences().setElementAt(seqs[i],i);\r
82     }\r
83   }\r
84 \r
85   /**    */\r
86   static boolean sortIdAscending = true;\r
87   public static void sortByID(AlignmentI align) {\r
88     int nSeq = align.getHeight();\r
89 \r
90     String    ids[]   = new String[nSeq];\r
91     SequenceI seqs[]  = new SequenceI[nSeq];\r
92 \r
93     for (int i = 0; i < nSeq; i++) {\r
94       ids[i]  = align.getSequenceAt(i).getName();\r
95       seqs[i] = align.getSequenceAt(i);\r
96     }\r
97 \r
98     QuickSort.sort(ids,seqs);\r
99 \r
100     if(sortIdAscending)\r
101       setReverseOrder(align,seqs);\r
102     else\r
103       setOrder(align, seqs);\r
104 \r
105     sortIdAscending = !sortIdAscending;\r
106   }\r
107 \r
108   static boolean sortGroupAscending = true;\r
109   public static void sortByGroup(AlignmentI align) {\r
110     int    nSeq = align.getHeight();\r
111     Vector groups = align.getGroups();\r
112 \r
113     Vector seqs = new Vector();\r
114 \r
115     for (int i=0; i < groups.size(); i++) {\r
116       SequenceGroup sg = (SequenceGroup)groups.elementAt(i);\r
117 \r
118       for (int j = 0; j < sg.getSize(); j++) {\r
119         seqs.addElement(sg.getSequenceAt(j));\r
120       }\r
121     }\r
122 \r
123     if (seqs.size() != nSeq) {\r
124       System.err.println("ERROR: tmp.size() != nseq in sortByGroups");\r
125       if (seqs.size() < nSeq) {\r
126         addStrays(align,seqs);\r
127       }\r
128     }\r
129 \r
130     if(sortGroupAscending)\r
131       setOrder(align,seqs);\r
132     else\r
133       setReverseOrder( align, vectorToArray(seqs));\r
134 \r
135     sortGroupAscending = ! sortGroupAscending;\r
136   }\r
137 \r
138   private static SequenceI [] vectorToArray(Vector tmp) {\r
139     SequenceI[] seqs = new SequenceI[tmp.size()];\r
140 \r
141     for (int i=0; i < tmp.size(); i++) {\r
142       seqs[i] = (SequenceI)tmp.elementAt(i);\r
143     }\r
144     return seqs;\r
145   }\r
146 \r
147   static boolean sortTreeAscending = true;\r
148   public static void sortByTree(AlignmentI align, NJTree tree) {\r
149     int    nSeq = align.getHeight();\r
150 \r
151     Vector tmp = new Vector();\r
152 \r
153     tmp = _sortByTree(tree.getTopNode(),tmp);\r
154 \r
155     if (tmp.size() != nSeq) {\r
156       System.err.println("ERROR: tmp.size() != nseq in sortByTree");\r
157       if (tmp.size() < nSeq) {\r
158         addStrays(align,tmp);\r
159       }\r
160     }\r
161 \r
162     if(sortTreeAscending)\r
163       setOrder(align,tmp);\r
164     else\r
165       setReverseOrder(align, vectorToArray(tmp));\r
166 \r
167       sortTreeAscending = !sortTreeAscending;\r
168   }\r
169 \r
170   private static void addStrays(AlignmentI align, Vector seqs) {\r
171     int    nSeq = align.getHeight();\r
172     for (int i=0;i<nSeq;i++) {\r
173       if (!seqs.contains(align.getSequenceAt(i))) {\r
174         seqs.addElement(align.getSequenceAt(i));\r
175       }\r
176     }\r
177     if (nSeq != seqs.size()) {\r
178       System.err.println("ERROR: Size still not right even after addStrays");\r
179     }\r
180   }\r
181 \r
182   public static Vector _sortByTree(SequenceNode node, Vector tmp) {\r
183     if (node == null) {return tmp;}\r
184 \r
185     SequenceNode left = (SequenceNode)node.left();\r
186     SequenceNode right = (SequenceNode)node.right();\r
187 \r
188     if (left == null && right == null) {\r
189       if (node.element() instanceof SequenceI) {\r
190         tmp.addElement((SequenceI)node.element());\r
191         return tmp;\r
192       }\r
193     } else {\r
194       _sortByTree(left,tmp);\r
195       _sortByTree(right,tmp);\r
196     }\r
197     return tmp;\r
198   }\r
199 }\r