label.neighbour_blosum62 = Neighbour Joining Using BLOSUM62
label.show_annotations = Show annotations
label.hide_annotations = Hide annotations
-label.show_all_annotations = Show all annotations
-label.hide_all_annotations = Hide all annotations
+label.show_all_annotations = Show all
+label.hide_all_annotations = Hide all
label.hide_all = Hide all
label.add_reference_annotations = Add reference annotations
label.find_tip = Search alignment, selection or sequence ids for a subsequence (ignoring gaps).<br>Accepts regular expressions - search Help for 'regex' for details.
label.sort_by_score = Sort by Score
label.sort_by_density = Sort by Density
label.sequence_sort_by_density = Sequence sort by Density
-label.sort_annotations_by_sequence = Sort annotations by sequence order
-label.sort_annotations_by_type = Sort annotations by type
+label.sort_annotations_by_sequence = Sort by sequence
+label.sort_annotations_by_type = Sort by type
label.reveal = Reveal
label.hide_columns = Hide Columns
label.load_jalview_annotations = Load Jalview Annotations or Features File
public class AnnotationSorter
{
+ public enum SortOrder
+ {
+ SEQUENCE_AND_TYPE, TYPE_AND_SEQUENCE
+ }
+
private final AlignmentI alignment;
public AnnotationSorter(AlignmentI alignmentI)
}
};
+ private final Comparator<? super AlignmentAnnotation> DEFAULT_COMPARATOR = bySequenceAndType;
+
/**
- * Sort by annotation type (label), within sequence order.
- * Non-sequence-related annotations sort to the end.
+ * Sort by the specified order.
*
* @param alignmentAnnotations
+ * @param order
*/
- public void sortBySequenceAndType(
- AlignmentAnnotation[] alignmentAnnotations)
+ public void sort(AlignmentAnnotation[] alignmentAnnotations,
+ SortOrder order)
{
+ Comparator<? super AlignmentAnnotation> comparator = getComparator(order);
+
if (alignmentAnnotations != null)
{
synchronized (alignmentAnnotations)
{
- Arrays.sort(alignmentAnnotations, bySequenceAndType);
+ Arrays.sort(alignmentAnnotations, comparator);
}
}
}
/**
- * Sort by sequence order within annotation type (label). Non-sequence-related
- * annotations sort to the end.
+ * Get the comparator for the specified sort order.
*
- * @param alignmentAnnotations
+ * @param order
+ * @return
*/
- public void sortByTypeAndSequence(
- AlignmentAnnotation[] alignmentAnnotations)
+ private Comparator<? super AlignmentAnnotation> getComparator(
+ SortOrder order)
{
- if (alignmentAnnotations != null)
+ if (order == null)
{
- synchronized (alignmentAnnotations)
- {
- Arrays.sort(alignmentAnnotations, byTypeAndSequence);
- }
+ return DEFAULT_COMPARATOR;
+ }
+ switch (order)
+ {
+ case SEQUENCE_AND_TYPE:
+ return this.bySequenceAndType;
+ case TYPE_AND_SEQUENCE:
+ return this.byTypeAndSequence;
+ default:
+ throw new UnsupportedOperationException(order.toString());
}
}
import jalview.ws.dbsources.das.datamodel.DasSourceRegistry;
import java.awt.Color;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.Date;
+import java.util.Properties;
-import org.apache.log4j.*;
+import org.apache.log4j.ConsoleAppender;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.log4j.SimpleLayout;
/**
* Stores and retrieves Jalview Application Properties Lists and fields within
* <li>SHOW_QUALITY show alignment quality annotation</li>
* <li>SHOW_ANNOTATIONS show alignment annotation rows</li>
* <li>SHOW_CONSERVATION show alignment conservation annotation</li>
+ * <li>SORT_ANNOTATIONS currently either SEQUENCE_AND_TYPE or TYPE_AND_SEQUENCE</li>
* <li>CENTRE_COLUMN_LABELS centre the labels at each column in a displayed
* annotation row</li>
* <li>DEFAULT_COLOUR default colour scheme to apply for a new alignment</li>
if (log != null)
{
if (re != null)
+ {
log.debug("Caught runtime exception in googletracker init:", re);
+ }
if (ex != null)
+ {
log.warn(
"Failed to initialise GoogleTracker for Jalview Desktop with version "
+ vrs, ex);
+ }
if (err != null)
+ {
log.error(
"Whilst initing GoogleTracker for Jalview Desktop version "
+ vrs, err);
+ }
}
else
{
import jalview.analysis.AAFrequency;
import jalview.analysis.AlignmentSorter;
import jalview.analysis.AlignmentUtils;
-import jalview.analysis.AnnotationSorter;
+import jalview.analysis.AnnotationSorter.SortOrder;
import jalview.analysis.Conservation;
import jalview.analysis.CrossRef;
import jalview.analysis.NJTree;
this.alignPanel.paintAlignment(true);
}
+ /**
+ * Store selected annotation sort order for the view and repaint.
+ */
@Override
- protected void sortAnnotationsByType_actionPerformed()
- {
- AnnotationSorter sorter = new AnnotationSorter(
- this.alignPanel.getAlignment());
- sorter.sortByTypeAndSequence(this.alignPanel.getAlignment()
- .getAlignmentAnnotation());
- alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
- }
-
- @Override
- protected void sortAnnotationsBySequence_actionPerformed()
+ protected void sortAnnotations_actionPerformed(SortOrder sortOrder)
{
- AnnotationSorter sorter = new AnnotationSorter(
- this.alignPanel.getAlignment());
- sorter.sortBySequenceAndType(this.alignPanel.getAlignment()
- .getAlignmentAnnotation());
+ this.alignPanel.av.setSortAnnotationsBy(sortOrder);
alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
}
}
*/
package jalview.gui;
+import jalview.analysis.AnnotationSorter.SortOrder;
import jalview.analysis.NJTree;
import jalview.api.AlignViewportI;
import jalview.bin.Cache;
boolean showAnnotation = true;
+ SortOrder sortAnnotationsBy = null;
+
int charHeight;
int charWidth;
}
}
- wrapAlignment = jalview.bin.Cache.getDefault("WRAP_ALIGNMENT", false);
- showUnconserved = jalview.bin.Cache.getDefault("SHOW_UNCONSERVED",
+ wrapAlignment = Cache.getDefault("WRAP_ALIGNMENT", false);
+ showUnconserved = Cache.getDefault("SHOW_UNCONSERVED",
false);
- sortByTree = jalview.bin.Cache.getDefault("SORT_BY_TREE", false);
- followSelection = jalview.bin.Cache.getDefault("FOLLOW_SELECTIONS",
+ sortByTree = Cache.getDefault("SORT_BY_TREE", false);
+ followSelection = Cache.getDefault("FOLLOW_SELECTIONS",
true);
+ sortAnnotationsBy = SortOrder.valueOf(Cache.getDefault(
+ "SORT_ANNOTATIONS", SortOrder.SEQUENCE_AND_TYPE.name()));
}
/**
{
// TODO: JAL-1126
if (historyList == null || redoList == null)
+ {
return new long[]
{ -1, -1 };
+ }
return new long[]
{ historyList.hashCode(), this.redoList.hashCode() };
}
Vector pdbs = alignment.getSequenceAt(i).getDatasetSequence()
.getPDBId();
if (pdbs == null)
+ {
continue;
+ }
SequenceI sq;
for (int p = 0; p < pdbs.size(); p++)
{
if (p1.getId().equals(pdb.getId()))
{
if (!seqs.contains(sq = alignment.getSequenceAt(i)))
+ {
seqs.add(sq);
+ }
continue;
}
Cache.log.debug("trigger update for " + calcId);
}
}
+
+ protected SortOrder getSortAnnotationsBy()
+ {
+ return sortAnnotationsBy;
+ }
+
+ protected void setSortAnnotationsBy(SortOrder sortAnnotationsBy)
+ {
+ this.sortAnnotationsBy = sortAnnotationsBy;
+ }
}
*/
package jalview.gui;
-import java.beans.*;
-import java.io.*;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.print.*;
-import javax.swing.*;
-
+import jalview.analysis.AnnotationSorter;
import jalview.api.AlignmentViewPanel;
import jalview.bin.Cache;
-import jalview.datamodel.*;
-import jalview.jbgui.*;
-import jalview.schemes.*;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.jbgui.GAlignmentPanel;
+import jalview.schemes.ResidueProperties;
import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+
+import javax.swing.SwingUtilities;
+
/**
* DOCUMENT ME!
*
int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
int maxwidth = Math.max(20,
- Math.min(afwidth - 200, (int) 2 * afwidth / 3));
+ Math.min(afwidth - 200, 2 * afwidth / 3));
return calculateIdWidth(maxwidth);
}
}
}
+ /**
+ * Repaint the alignment including the annotations and overview panels (if
+ * shown).
+ */
public void paintAlignment(boolean updateOverview)
{
+ new AnnotationSorter(getAlignment()).sort(getAlignment()
+ .getAlignmentAnnotation(),
+ av.getSortAnnotationsBy());
repaint();
if (updateOverview)
// / How many sequences and residues can we fit on a printable page?
int totalRes = (pwidth - idWidth) / av.getCharWidth();
- int totalSeq = (int) ((pheight - scaleHeight) / av.getCharHeight()) - 1;
+ int totalSeq = (pheight - scaleHeight) / av.getCharHeight() - 1;
int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1;
int offset = -alabels.scrollOffset;
pg.translate(0, offset);
pg.translate(-idWidth - 3, (endSeq - startSeq) * av.charHeight + 3);
- alabels.drawComponent((Graphics2D) pg, idWidth);
+ alabels.drawComponent(pg, idWidth);
pg.translate(idWidth + 3, 0);
annotationPanel.renderer.drawComponent(annotationPanel, av,
- (Graphics2D) pg, -1, startRes, endRes + 1);
+ pg, -1, startRes, endRes + 1);
pg.translate(0, -offset);
}
import jalview.analysis.AAFrequency;
import jalview.analysis.AlignmentAnnotationUtils;
import jalview.analysis.AnnotationSorter;
+import jalview.analysis.AnnotationSorter.SortOrder;
import jalview.analysis.Conservation;
import jalview.commands.ChangeCaseCommand;
import jalview.commands.EditCommand;
}
// TODO: save annotation sort order on AlignViewport
// do sorting from AlignmentPanel.updateAnnotation()
- new AnnotationSorter(this.ap.getAlignment())
- .sortBySequenceAndType(this.ap.getAlignment()
- .getAlignmentAnnotation());
+ new AnnotationSorter(this.ap.getAlignment()).sort(this.ap
+ .getAlignment().getAlignmentAnnotation(),
+ SortOrder.SEQUENCE_AND_TYPE);
refresh();
}
*/
package jalview.jbgui;
+import jalview.analysis.AnnotationSorter.SortOrder;
import jalview.bin.Cache;
import jalview.gui.JvSwingUtils;
import jalview.schemes.ColourSchemeProperty;
protected JMenuItem hideAllAnnotations = new JMenuItem();
- protected JMenuItem sortAnnBySequence = new JMenuItem();
+ protected JCheckBoxMenuItem sortAnnBySequence = new JCheckBoxMenuItem();
- protected JMenuItem sortAnnByType = new JMenuItem();
+ protected JCheckBoxMenuItem sortAnnByType = new JCheckBoxMenuItem();
protected JCheckBoxMenuItem hiddenMarkers = new JCheckBoxMenuItem();
@Override
public void actionPerformed(ActionEvent e)
{
- sortAnnotationsBySequence_actionPerformed();
+ sortAnnBySequence.setEnabled(false);
+ sortAnnBySequence.setState(true);
+ sortAnnByType.setEnabled(true);
+ sortAnnByType.setState(false);
+ sortAnnotations_actionPerformed(SortOrder.SEQUENCE_AND_TYPE);
}
});
sortAnnByType.setText(MessageManager
@Override
public void actionPerformed(ActionEvent e)
{
- sortAnnotationsByType_actionPerformed();
+ sortAnnByType.setEnabled(false);
+ sortAnnByType.setState(true);
+ sortAnnBySequence.setEnabled(true);
+ sortAnnBySequence.setState(false);
+ sortAnnotations_actionPerformed(SortOrder.TYPE_AND_SEQUENCE);
}
});
colourTextMenuItem.setText(MessageManager
/**
* Action on clicking sort annotations by type.
+ *
+ * @param sortOrder
*/
- protected void sortAnnotationsByType_actionPerformed()
- {
- }
-
- /**
- * Action on clicking sort annotations by sequence
- */
- protected void sortAnnotationsBySequence_actionPerformed()
+ protected void sortAnnotations_actionPerformed(SortOrder sortOrder)
{
}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import jalview.analysis.AnnotationSorter.SortOrder;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Sequence;
// @formatter:on
AnnotationSorter testee = new AnnotationSorter(al);
- testee.sortBySequenceAndType(anns);
+ testee.sort(anns, SortOrder.SEQUENCE_AND_TYPE);
assertEquals("label5", anns[0].label); // for sequence 0
assertEquals("label0", anns[1].label); // for sequence 1
assertEquals("iron", anns[2].label); // sequence 3 /iron
// @formatter:on
AnnotationSorter testee = new AnnotationSorter(al);
- testee.sortByTypeAndSequence(anns);
+ testee.sort(anns, SortOrder.TYPE_AND_SEQUENCE);
assertEquals("IRON", anns[0].label); // IRON / sequence 0
assertEquals("iron", anns[1].label); // iron / sequence 3
assertEquals("label0", anns[2].label); // label0 / sequence 1
}
@Test
- public void testSortBySequenceAndType_timing()
+ public void testSort_timingPresorted()
{
- final long targetTime = 300; // ms
+ final long targetTime = 100; // ms
final int numSeqs = 10000;
final int numAnns = 20000;
al = buildAlignment(numSeqs);
anns = buildAnnotations(numAnns);
/*
- * Set the annotations in random order with respect to the sequences
+ * Set the annotations presorted by label
*/
Random r = new Random();
final SequenceI[] sequences = al.getSequencesArray();
{
SequenceI randomSequenceRef = sequences[r.nextInt(sequences.length)];
anns[i].sequenceRef = randomSequenceRef;
+ anns[i].label = "label" + i;
}
long startTime = System.currentTimeMillis();
AnnotationSorter testee = new AnnotationSorter(al);
- testee.sortByTypeAndSequence(anns);
+ testee.sort(anns, SortOrder.TYPE_AND_SEQUENCE);
long endTime = System.currentTimeMillis();
final long elapsed = endTime - startTime;
- System.out.println("Timing test for " + numSeqs + " sequences and "
+ System.out.println("Timing test for presorted " + numSeqs
+ + " sequences and "
+ numAnns + " annotations took " + elapsed + "ms");
assertTrue("Sort took more than " + targetTime + "ms",
elapsed <= targetTime);
}
+
+ /**
+ * Timing test for sorting randomly sorted annotations
+ */
+ @Test
+ public void testSort_timingUnsorted()
+ {
+ final int numSeqs = 2000;
+ final int numAnns = 4000;
+ al = buildAlignment(numSeqs);
+ anns = buildAnnotations(numAnns);
+
+ /*
+ * Set the annotations in random order with respect to the sequences
+ */
+ Random r = new Random();
+ final SequenceI[] sequences = al.getSequencesArray();
+ for (int i = 0; i < anns.length; i++)
+ {
+ SequenceI randomSequenceRef = sequences[r.nextInt(sequences.length)];
+ anns[i].sequenceRef = randomSequenceRef;
+ anns[i].label = "label" + i;
+ }
+ long startTime = System.currentTimeMillis();
+ AnnotationSorter testee = new AnnotationSorter(al);
+ testee.sort(anns, SortOrder.SEQUENCE_AND_TYPE);
+ long endTime = System.currentTimeMillis();
+ final long elapsed = endTime - startTime;
+ System.out.println("Timing test for unsorted " + numSeqs
+ + " sequences and "
+ + numAnns + " annotations took " + elapsed + "ms");
+ }
+
+ /**
+ * Timing test for sorting annotations with a limited range of types (labels).
+ */
+ @Test
+ public void testSort_timingSemisorted()
+ {
+ final int numSeqs = 2000;
+ final int numAnns = 4000;
+ al = buildAlignment(numSeqs);
+ anns = buildAnnotations(numAnns);
+
+ String[] labels = new String[]
+ { "label1", "label2", "label3", "label4", "label5", "label6" };
+
+ /*
+ * Set the annotations in sequence order with randomly assigned labels.
+ */
+ Random r = new Random();
+ final SequenceI[] sequences = al.getSequencesArray();
+ for (int i = 0; i < anns.length; i++)
+ {
+ SequenceI sequenceRef = sequences[i % sequences.length];
+ anns[i].sequenceRef = sequenceRef;
+ anns[i].label = labels[r.nextInt(labels.length)];
+ }
+ long startTime = System.currentTimeMillis();
+ AnnotationSorter testee = new AnnotationSorter(al);
+ testee.sort(anns, SortOrder.TYPE_AND_SEQUENCE);
+ long endTime = System.currentTimeMillis();
+ long elapsed = endTime - startTime;
+ System.out.println("Sort by type for semisorted " + numSeqs
+ + " sequences and "
+ + numAnns + " annotations took " + elapsed + "ms");
+
+ // now resort by sequence
+ startTime = System.currentTimeMillis();
+ testee.sort(anns, SortOrder.SEQUENCE_AND_TYPE);
+ endTime = System.currentTimeMillis();
+ elapsed = endTime - startTime;
+ System.out.println("Resort by sequence for semisorted " + numSeqs
+ + " sequences and " + numAnns + " annotations took " + elapsed
+ + "ms");
+
+ // now resort by type
+ startTime = System.currentTimeMillis();
+ testee.sort(anns, SortOrder.TYPE_AND_SEQUENCE);
+ endTime = System.currentTimeMillis();
+ elapsed = endTime - startTime;
+ System.out.println("Resort by type for semisorted " + numSeqs
+ + " sequences and " + numAnns + " annotations took " + elapsed
+ + "ms");
+ }
}