package jalview.io;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
import java.util.Arrays;
import java.util.Comparator;
public class AlignmentProperties
{
private static final String BR_TAG = "<br>";
+
private static final String NEWLINE = System.getProperty("line.separator");
+
+ private static final String PCT_FORMAT = "%.1f%%";
+
AlignmentI alignment;
public AlignmentProperties(AlignmentI alignment)
{
StringBuilder sb = new StringBuilder(256);
final String nl = html ? BR_TAG : NEWLINE;
- float avg = 0;
- int min = Integer.MAX_VALUE, max = 0;
- for (int i = 0; i < alignment.getHeight(); i++)
+ int totalLength = 0;
+ int totalGaps = 0;
+ int minLength = Integer.MAX_VALUE;
+ int maxLength = 0;
+ float maxUngapped = 0f;
+ float minUngapped = Float.MAX_VALUE;
+
+ final int height = alignment.getHeight();
+ final int width = alignment.getWidth();
+
+ for (int i = 0; i < height; i++)
{
- int size = 1 + alignment.getSequenceAt(i).getEnd()
- - alignment.getSequenceAt(i).getStart();
- avg += size;
- if (size > max)
- {
- max = size;
- }
- if (size < min)
- {
- min = size;
- }
+ SequenceI seq = alignment.getSequenceAt(i);
+ // sequence length including gaps:
+ int seqWidth = seq.getLength();
+ // sequence length excluding gaps:
+ int seqLength = 1 + seq.getEnd() - seq.getStart();
+ int gapCount = seqWidth - seqLength; // includes padding
+ totalLength += seqLength;
+ totalGaps += gapCount;
+ maxLength = Math.max(maxLength, seqLength);
+ minLength = Math.min(minLength, seqLength);
+
+ /*
+ * proportion of aligned sequence that is ungapped
+ * (note: not normalised by alignment width here)
+ */
+ float ungapped = (seqLength - gapCount) / (float) seqLength;
+ maxUngapped = Math.max(maxUngapped, ungapped);
+ minUngapped = Math.min(minUngapped, ungapped);
}
- avg = avg / alignment.getHeight();
- sb.append(nl);
- sb.append("Sequences: " + alignment.getHeight());
- sb.append(nl);
- sb.append("Minimum Sequence Length: " + min);
- sb.append(nl);
- sb.append("Maximum Sequence Length: " + max);
- sb.append(nl);
- sb.append("Average Length: " + (int) avg);
+ float avgLength = totalLength / (float) height;
+
+ sb.append(html ? "<table border=\"1\">" : nl);
+ appendRow(sb, "Sequences", String.valueOf(height), html);
+ appendRow(sb, "Alignment width", String.valueOf(width),
+ html);
+ appendRow(sb, "Minimum Sequence Length", String.valueOf(minLength),
+ html);
+ appendRow(sb, "Maximum Sequence Length", String.valueOf(maxLength),
+ html);
+ appendRow(sb, "Average Length", String.valueOf((int) avgLength), html);
+ appendRow(sb, "Minimum (sequence length / width)",
+ String.format(PCT_FORMAT, minUngapped * 100f), html);
+ appendRow(sb, "Maximum (sequence length / width)",
+ String.format(PCT_FORMAT, maxUngapped * 100f), html);
+ appendRow(sb, "Residue density", String.format(PCT_FORMAT,
+ (totalLength - totalGaps) * 100f / totalLength), html);
+ appendRow(sb, "Gap density",
+ String.format(PCT_FORMAT, totalGaps * 100f / totalLength),
+ html);
+ sb.append(html ? "</table>" : nl);
Map<Object, Object> props = alignment.getProperties();
if (props != null && !props.isEmpty())