1 package jalview.analysis;
3 import jalview.datamodel.AlignmentI;
4 import jalview.datamodel.SequenceFeature;
5 import jalview.datamodel.SequenceGroup;
6 import jalview.datamodel.SequenceI;
8 import java.util.Enumeration;
9 import java.util.Hashtable;
10 import java.util.Vector;
13 * various methods for defining groups on an alignment based on some other properties
20 * Divide the given sequences based on the equivalence of their corresponding selectedChars string. If exgroups is provided, existing groups will be subdivided.
22 * @param selectedChars
26 public static SequenceGroup[] makeGroupsFrom(SequenceI[] sequences, String[] selectedChars, Vector exgroups)
28 // TODO: determine how to get/recover input data for group generation
29 Hashtable gps = new Hashtable();
31 Hashtable pgroup = new Hashtable();
35 for (Enumeration g=exgroups.elements(); g.hasMoreElements(); )
37 sg = (SequenceGroup) g.nextElement();
38 for (Enumeration sq = sg.getSequences(null).elements(); sq.hasMoreElements(); )
39 pgroup.put(sq.nextElement().toString(), sg);
42 for (i = 0; i < sequences.length; i++)
44 String schar = selectedChars[i];
45 SequenceGroup pgp = (SequenceGroup) pgroup.get(((Object) sequences[i]).toString());
48 schar = pgp.getName()+":"+schar;
50 Vector svec = (Vector) gps.get(schar);
56 if (width<sequences[i].getLength())
58 width = sequences[i].getLength();
60 svec.addElement(sequences[i]);
63 java.util.Enumeration sge = gps.keys();
64 SequenceGroup[] groups = new SequenceGroup[gps.size()];
66 while (sge.hasMoreElements()) {
67 String key = (String) sge.nextElement();
68 SequenceGroup group = new SequenceGroup((Vector) gps.get(key), "Subseq: "+key, null, true, true,
78 * subdivide the given sequences based on the distribution of features
79 * @param featureLabels - null or one or more feature types to filter on.
80 * @param groupLabels - null or set of groups to filter features on
81 * @param start - range for feature filter
82 * @param stop - range for feature filter
83 * @param sequences - sequences to be divided
84 * @param exgroups - existing groups to be subdivided
85 * @param method - density, description, score
87 public static void divideByFeature(String[] featureLabels, String[] groupLabels, int start, int stop,
88 SequenceI[] sequences, Vector exgroups, String method)
90 // TODO implement divideByFeature
92 if (method!=AlignmentSorter.FEATURE_SCORE && method!=AlignmentSorter.FEATURE_LABEL && method!=AlignmentSorter.FEATURE_DENSITY)
94 throw new Error("Implementation Error - sortByFeature method must be one of FEATURE_SCORE, FEATURE_LABEL or FEATURE_DENSITY.");
96 boolean ignoreScore=method!=AlignmentSorter.FEATURE_SCORE;
97 StringBuffer scoreLabel = new StringBuffer();
98 scoreLabel.append(start+stop+method);
99 // This doesn't work yet - we'd like to have a canonical ordering that can be preserved from call to call
100 for (int i=0;featureLabels!=null && i<featureLabels.length; i++)
102 scoreLabel.append(featureLabels[i]==null ? "null" : featureLabels[i]);
104 for (int i=0;groupLabels!=null && i<groupLabels.length; i++)
106 scoreLabel.append(groupLabels[i]==null ? "null" : groupLabels[i]);
108 SequenceI[] seqs = alignment.getSequencesArray();
110 boolean[] hasScore = new boolean[seqs.length]; // per sequence score
112 int hasScores = 0; // number of scores present on set
113 double[] scores = new double[seqs.length];
114 int[] seqScores = new int[seqs.length];
115 Object[] feats = new Object[seqs.length];
116 double min = 0, max = 0;
117 for (int i = 0; i < seqs.length; i++)
119 SequenceFeature[] sf = seqs[i].getSequenceFeatures();
120 if (sf==null && seqs[i].getDatasetSequence()!=null)
122 sf = seqs[i].getDatasetSequence().getSequenceFeatures();
126 sf = new SequenceFeature[0];
128 SequenceFeature[] tmp = new SequenceFeature[sf.length];
129 for (int s=0; s<tmp.length;s++)
135 int sstart = (start==-1) ? start : seqs[i].findPosition(start);
136 int sstop = (stop==-1) ? stop : seqs[i].findPosition(stop);
140 for (int f=0;f<sf.length;f++)
142 // filter for selection criteria
144 // ignore features outwith alignment start-stop positions.
145 (sf[f].end < sstart || sf[f].begin > sstop)
147 // or ignore based on selection criteria
148 (featureLabels != null && !AlignmentSorter.containsIgnoreCase(sf[f].type, featureLabels))
149 || (groupLabels != null
150 // problem here: we cannot eliminate null feature group features
151 && (sf[f].getFeatureGroup() != null
152 && !AlignmentSorter.containsIgnoreCase(sf[f].getFeatureGroup(), groupLabels))))
154 // forget about this feature
158 // or, also take a look at the scores if necessary.
159 if (!ignoreScore && sf[f].getScore()!=Float.NaN)
167 scores[i] += sf[f].getScore(); // take the first instance of this
172 SequenceFeature[] fs;
173 feats[i] = fs = new SequenceFeature[n];
177 for (int f=0;f<sf.length;f++)
181 ((SequenceFeature[]) feats[i])[n++] = sf[f];
184 if (method==FEATURE_LABEL)
186 // order the labels by alphabet
187 String[] labs = new String[fs.length];
188 for (int l=0;l<labs.length; l++)
190 labs[l] = (fs[l].getDescription()!=null ? fs[l].getDescription() : fs[l].getType());
192 jalview.util.QuickSort.sort(labs, ((Object[]) feats[i]));
197 // compute average score
198 scores[i]/=seqScores[i];
199 // update the score bounds.
202 max = min = scores[i];
218 if (method==FEATURE_SCORE)
222 return; // do nothing - no scores present to sort by.
225 if (hasScores < seqs.length)
227 for (int i = 0; i < seqs.length; i++)
231 scores[i] = (max + i);
233 int nf=(feats[i]==null) ? 0 :((SequenceFeature[]) feats[i]).length;
234 System.err.println("Sorting on Score: seq "+seqs[i].getName()+ " Feats: "+nf+" Score : "+scores[i]);
239 jalview.util.QuickSort.sort(scores, seqs);
242 if (method==FEATURE_DENSITY)
245 // break ties between equivalent numbers for adjacent sequences by adding 1/Nseq*i on the original order
246 double fr = 0.9/(1.0*seqs.length);
247 for (int i=0;i<seqs.length; i++)
250 scores[i] = (0.05+fr*i)+(nf=((feats[i]==null) ? 0.0 :1.0*((SequenceFeature[]) feats[i]).length));
251 System.err.println("Sorting on Density: seq "+seqs[i].getName()+ " Feats: "+nf+" Score : "+scores[i]);
253 jalview.util.QuickSort.sort(scores, seqs);
256 if (method==FEATURE_LABEL)
258 throw new Error("Not yet implemented.");
261 if (lastSortByFeatureScore ==null || scoreLabel.equals(lastSortByFeatureScore))
263 setOrder(alignment, seqs);
267 setReverseOrder(alignment, seqs);
269 lastSortByFeatureScore = scoreLabel.toString(); */