From: kiramt Date: Fri, 5 May 2017 09:35:48 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/develop' into X-Git-Tag: Release_2_10_2~3^2~92^2~3^2~1 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=e5b2edf3955c50cfd61799ad12cdc9016603ee1c;hp=df98ae3e601ff44c9a1d7beb5c9014aebf0e960e;p=jalview.git Merge remote-tracking branch 'origin/develop' into features/JAL-2388hiddencolumnschanges Conflicts: src/jalview/gui/AnnotationColumnChooser.java src/jalview/io/AnnotationFile.java --- diff --git a/examples/appletParameters.html b/examples/appletParameters.html index 7959c3a..04cc235 100644 --- a/examples/appletParameters.html +++ b/examples/appletParameters.html @@ -159,6 +159,11 @@ the applet can be interacted with via its Default is true. + showOccupancy + true or false + Default is true. + + sortBy Id , Pairwise Identity, or Length Sorts the alignment on startup diff --git a/examples/testdata/example_annot_file.jva b/examples/testdata/example_annot_file.jva index 794f42b..1779247 100644 --- a/examples/testdata/example_annot_file.jva +++ b/examples/testdata/example_annot_file.jva @@ -18,5 +18,5 @@ SEQUENCE_GROUP Group_A 30 50 * SEQUENCE_GROUP Group_B 1 351 2-5 SEQUENCE_GROUP Group_C 12 14 -1 seq1 seq2 seq3 PROPERTIES Group_A description=This is the description colour=Helix Propensity pidThreshold=0 outlineColour=red displayBoxes=true displayText=false colourText=false textCol1=black textCol2=black textColThreshold=0 -PROPERTIES Group_B outlineColour=red +PROPERTIES Group_B outlineColour=red colour=None PROPERTIES Group_C colour=Clustal diff --git a/help/html/features/preferences.html b/help/html/features/preferences.html index da045ba..6e8d3e4 100755 --- a/help/html/features/preferences.html +++ b/help/html/features/preferences.html @@ -89,10 +89,11 @@

Show Annotations - If this is selected the new window will display an annotation panel below the sequences. This annotation - panel may have several rows describing the whole alignment. The 3 - standard annotations Conservation, Quality and Consensus - for the alignment may be shown or hidden by default using the - checkboxes below. + panel may have several rows describing the whole alignment. The 4 + standard annotations Conservation, Quality, + Occupancy and Consensus for the alignment may + be shown or hidden by default using the checkboxes adjacent and + below.

Show group: Conservation and Consensus controls the display diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 4ebca62..922f482 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -181,6 +181,7 @@ label.score_model_conservation = Physicochemical property conservation label.score_model_enhconservation = Physicochemical property conservation label.status_bar = Status bar label.out_to_textbox = Output to Textbox +label.occupancy = Occupancy # delete Clustal - use FileFormat name instead label.clustal = Clustal # label.colourScheme_ as in JalviewColourScheme @@ -908,6 +909,7 @@ label.webservice_job_title_on = {0} using {1} on {2} label.updating_vamsas_session = Updating vamsas session label.loading_file = Loading File: {0} label.edit_params = Edit {0} +label.as_percentage = As Percentage error.not_implemented = Not implemented error.no_such_method_as_clone1_for = No such method as clone1 for {0} error.null_from_clone1 = Null from clone1! @@ -1297,3 +1299,9 @@ warn.name_cannot_be_duplicate = User-defined URL names must be unique and cannot label.invalid_name = Invalid Name ! label.output_seq_details = Output Sequence Details to list all database references label.urllinks = Links +label.quality_descr = Alignment Quality based on Blosum62 scores +label.conservation_descr = Conservation of total alignment less than {0}% gaps +label.consensus_descr = PID +label.complement_consensus_descr = PID for cDNA +label.strucconsensus_descr = PID for base pairs +label.occupancy_descr = Number of aligned positions \ No newline at end of file diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index bdd61fe..e6e1872 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -178,6 +178,7 @@ label.score_model_conservation = Conservaci label.score_model_enhconservation = Conservación de las propiedades físico-químicas label.status_bar = Barra de estado label.out_to_textbox = Generar cuadro de texto +label.occupancy = Ocupación label.clustal = Clustal # label.colourScheme_ as in JalviewColourScheme label.colourScheme_clustal = Clustalx @@ -834,6 +835,7 @@ label.webservice_job_title_on = {0} usando {1} de {2} label.updating_vamsas_session = Actualizando sesión VAMSAS label.loading_file = Cargando fichero: {0} label.edit_params = Editar {0} +label.as_percentage = Como Porcentaje error.not_implemented = No implementado error.no_such_method_as_clone1_for = No existe ese método como un clone1 de {0} error.null_from_clone1 = Nulo de clone1! diff --git a/src/jalview/analysis/AAFrequency.java b/src/jalview/analysis/AAFrequency.java index ee16f94..b806355 100755 --- a/src/jalview/analysis/AAFrequency.java +++ b/src/jalview/analysis/AAFrequency.java @@ -20,10 +20,6 @@ */ package jalview.analysis; -import java.util.Arrays; -import java.util.Hashtable; -import java.util.List; - import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; @@ -41,6 +37,11 @@ import jalview.util.Format; import jalview.util.MappingUtils; import jalview.util.QuickSort; +import java.awt.Color; +import java.util.Arrays; +import java.util.Hashtable; +import java.util.List; + /** * Takes in a vector or array of sequences and column start and column end and * returns a new Hashtable[] of size maxSeqLength, if Hashtable not supplied. @@ -315,6 +316,7 @@ public class AAFrequency // always set ranges again gaprow.graphMax = nseq; gaprow.graphMin = 0; + double scale = 0.8/nseq; for (int i = startCol; i < endCol; i++) { ProfileI profile = profiles.get(i); @@ -330,11 +332,11 @@ public class AAFrequency final int gapped = profile.getNonGapped(); - String description = String.valueOf(gapped); + String description = "" + gapped; - gaprow.annotations[i] = new Annotation(description, description, - '\0', - gapped); + gaprow.annotations[i] = new Annotation("", description, + '\0', gapped, jalview.util.ColorUtils.bleachColour( + Color.DARK_GRAY, (float) scale * gapped)); } } diff --git a/src/jalview/appletgui/AlignViewport.java b/src/jalview/appletgui/AlignViewport.java index d11ed48..61621ae 100644 --- a/src/jalview/appletgui/AlignViewport.java +++ b/src/jalview/appletgui/AlignViewport.java @@ -150,6 +150,9 @@ public class AlignViewport extends AlignmentViewport implements showConsensus = applet.getDefaultParameter("showConsensus", showConsensus); + showOccupancy = applet.getDefaultParameter("showOccupancy", + showOccupancy); + setShowUnconserved(applet.getDefaultParameter("showUnconserved", getShowUnconserved())); diff --git a/src/jalview/appletgui/AnnotationColumnChooser.java b/src/jalview/appletgui/AnnotationColumnChooser.java index 7efb490..2acb568 100644 --- a/src/jalview/appletgui/AnnotationColumnChooser.java +++ b/src/jalview/appletgui/AnnotationColumnChooser.java @@ -167,20 +167,22 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements } populateThresholdComboBox(threshold); - + AnnotationColumnChooser lastChooser = av + .getAnnotationColumnSelectionState(); // restore Object state from the previous session if one exists - if (av.getAnnotationColumnSelectionState() != null) + if (lastChooser != null) { - currentSearchPanel = av.getAnnotationColumnSelectionState() + currentSearchPanel = lastChooser .getCurrentSearchPanel(); - currentStructureFilterPanel = av.getAnnotationColumnSelectionState() + currentStructureFilterPanel = lastChooser .getCurrentStructureFilterPanel(); - annotations.select(av.getAnnotationColumnSelectionState() + annotations.select(lastChooser .getAnnotations().getSelectedIndex()); - threshold.select(av.getAnnotationColumnSelectionState() + threshold.select(lastChooser .getThreshold().getSelectedIndex()); - actionOption = av.getAnnotationColumnSelectionState() + actionOption = lastChooser .getActionOption(); + percentThreshold.setState(lastChooser.percentThreshold.getState()); } try @@ -204,6 +206,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements thresholdValue.setEnabled(false); thresholdValue.setColumns(7); + thresholdValue.setCaretPosition(0); ok.addActionListener(this); cancel.addActionListener(this); @@ -219,6 +222,9 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements // thresholdPanel.setFont(JvSwingUtils.getLabelFont()); // thresholdPanel.setLayout(new MigLayout("", "[left][right]", "[][]")); + percentThreshold.setLabel("As percentage"); + percentThreshold.addItemListener(this); + actionPanel.setBackground(Color.white); // actionPanel.setFont(JvSwingUtils.getLabelFont()); @@ -242,6 +248,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements thresholdPanel.add(getThreshold()); thresholdPanel.add(slider); thresholdPanel.add(thresholdValue); + thresholdPanel.add(percentThreshold); actionPanel.add(ok); actionPanel.add(cancel); @@ -313,7 +320,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements { if (!adjusting) { - thresholdValue.setText((slider.getValue() / 1000f) + ""); + setThresholdValueText(); valueChanged(!sliderDragging); } } @@ -399,12 +406,14 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements slider.setEnabled(true); thresholdValue.setEnabled(true); + percentThreshold.setEnabled(true); if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD) { slider.setEnabled(false); thresholdValue.setEnabled(false); thresholdValue.setText(""); + percentThreshold.setEnabled(false); // build filter params } else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD) @@ -425,10 +434,11 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements slider.setMinimum((int) (getCurrentAnnotation().graphMin * 1000)); slider.setMaximum((int) (getCurrentAnnotation().graphMax * 1000)); slider.setValue((int) (getCurrentAnnotation().threshold.value * 1000)); - thresholdValue.setText(getCurrentAnnotation().threshold.value + ""); + setThresholdValueText(); // slider.setMajorTickSpacing((int) (range / 10f)); slider.setEnabled(true); thresholdValue.setEnabled(true); + percentThreshold.setEnabled(true); adjusting = false; // build filter params @@ -574,6 +584,14 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements { threshold_actionPerformed(null); } + else if (e.getSource() == percentThreshold) + { + if (!adjusting) + { + percentageValue_actionPerformed(); + } + + } } public void selectedAnnotationChanged() @@ -877,19 +895,8 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements @Override public void actionPerformed(ActionEvent evt) { - if (evt.getSource() == thresholdValue) - { - try - { - float f = new Float(thresholdValue.getText()).floatValue(); - slider.setValue((int) (f * 1000)); - adjustmentValueChanged(null); - } catch (NumberFormatException ex) - { - } - } - else if (evt.getSource() == ok) + if (evt.getSource() == ok) { ok_actionPerformed(null); } diff --git a/src/jalview/appletgui/AnnotationRowFilter.java b/src/jalview/appletgui/AnnotationRowFilter.java index 8d67d71..315ce3b 100644 --- a/src/jalview/appletgui/AnnotationRowFilter.java +++ b/src/jalview/appletgui/AnnotationRowFilter.java @@ -31,7 +31,6 @@ import java.awt.Panel; import java.awt.Scrollbar; import java.awt.TextField; import java.awt.event.ActionEvent; -import java.util.Vector; @SuppressWarnings("serial") public abstract class AnnotationRowFilter extends Panel @@ -60,6 +59,8 @@ public abstract class AnnotationRowFilter extends Panel protected Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL); + protected Checkbox percentThreshold = new Checkbox(); + protected TextField thresholdValue = new TextField(20); protected Frame frame; @@ -132,18 +133,54 @@ public abstract class AnnotationRowFilter extends Panel updateView(); } + /** + * update the text field from the threshold slider. preserves state of + * 'adjusting' so safe to call in init. + */ + protected void setThresholdValueText() + { + boolean oldadj = adjusting; + adjusting = true; + if (percentThreshold.getState()) + { + double scl = slider.getMaximum() - slider.getMinimum(); + scl = (slider.getValue() - slider.getMinimum()) / scl; + thresholdValue.setText(100f * scl + ""); + } + else + { + thresholdValue.setText((slider.getValue() / 1000f) + ""); + } + thresholdValue.setCaretPosition(0); + adjusting = oldadj; + } + public void thresholdValue_actionPerformed(ActionEvent e) { try { float f = Float.parseFloat(thresholdValue.getText()); - slider.setValue((int) (f * 1000)); - updateView(); + if (percentThreshold.getState()) + { + int pos = slider.getMinimum() + + (int) ((slider.getMaximum() - slider.getMinimum()) * f / 100f); + slider.setValue(pos); + } + else + { + slider.setValue((int) (f * 1000)); + } + valueChanged(false); } catch (NumberFormatException ex) { } } + protected void percentageValue_actionPerformed() + { + setThresholdValueText(); + } + protected void populateThresholdComboBox(Choice threshold) { threshold.addItem(MessageManager diff --git a/src/jalview/datamodel/Alignment.java b/src/jalview/datamodel/Alignment.java index cff3890..fcb6109 100755 --- a/src/jalview/datamodel/Alignment.java +++ b/src/jalview/datamodel/Alignment.java @@ -1644,10 +1644,6 @@ public class Alignment implements AlignmentI return aa; } - /** - * Returns an iterable collection of any annotations that match on given - * sequence ref, calcId and label (ignoring null values). - */ @Override public Iterable findAnnotations(SequenceI seq, String calcId, String label) @@ -1655,9 +1651,11 @@ public class Alignment implements AlignmentI ArrayList aa = new ArrayList(); for (AlignmentAnnotation ann : getAlignmentAnnotation()) { - if (ann.getCalcId() != null && ann.getCalcId().equals(calcId) - && ann.sequenceRef != null && ann.sequenceRef == seq - && ann.label != null && ann.label.equals(label)) + if ((calcId == null || (ann.getCalcId() != null && ann.getCalcId() + .equals(calcId))) + && (seq == null || (ann.sequenceRef != null && ann.sequenceRef == seq)) + && (label == null || (ann.label != null && ann.label + .equals(label)))) { aa.add(ann); } diff --git a/src/jalview/datamodel/AlignmentView.java b/src/jalview/datamodel/AlignmentView.java index a61d0d1..5058dcf 100644 --- a/src/jalview/datamodel/AlignmentView.java +++ b/src/jalview/datamodel/AlignmentView.java @@ -972,14 +972,14 @@ public class AlignmentView if (start < fwidth) { viscontigs[nvis] = start; - viscontigs[nvis + 1] = fwidth; // end is inclusive + viscontigs[nvis + 1] = fwidth - 1; // end is inclusive nvis += 2; } return viscontigs; } else { - return new int[] { 0, width }; + return new int[] { 0, width - 1 }; } } diff --git a/src/jalview/datamodel/AnnotatedCollectionI.java b/src/jalview/datamodel/AnnotatedCollectionI.java index 3f6c515..2963fd5 100644 --- a/src/jalview/datamodel/AnnotatedCollectionI.java +++ b/src/jalview/datamodel/AnnotatedCollectionI.java @@ -40,6 +40,17 @@ public interface AnnotatedCollectionI extends SequenceCollectionI */ Iterable findAnnotation(String calcId); + /** + * Returns an iterable collection of any annotations that match on given + * sequence ref, calcId and label (ignoring null values). + * + * @param seq + * null or reference sequence to select annotation for + * @param calcId + * null or the calcId to select annotation for + * @param label + * null or the label to select annotation for + */ Iterable findAnnotations(SequenceI seq, String calcId, String label); diff --git a/src/jalview/datamodel/SequenceGroup.java b/src/jalview/datamodel/SequenceGroup.java index 1246d23..76ad093 100755 --- a/src/jalview/datamodel/SequenceGroup.java +++ b/src/jalview/datamodel/SequenceGroup.java @@ -1289,12 +1289,6 @@ public class SequenceGroup implements AnnotatedCollectionI return aa; } - /** - * Returns a list of annotations that match the specified sequenceRef, calcId - * and label, ignoring null values. - * - * @return list of AlignmentAnnotation objects - */ @Override public Iterable findAnnotations(SequenceI seq, String calcId, String label) @@ -1302,9 +1296,11 @@ public class SequenceGroup implements AnnotatedCollectionI ArrayList aa = new ArrayList(); for (AlignmentAnnotation ann : getAlignmentAnnotation()) { - if (ann.getCalcId() != null && ann.getCalcId().equals(calcId) - && ann.sequenceRef != null && ann.sequenceRef == seq - && ann.label != null && ann.label.equals(label)) + if ((calcId == null || (ann.getCalcId() != null && ann.getCalcId() + .equals(calcId))) + && (seq == null || (ann.sequenceRef != null && ann.sequenceRef == seq)) + && (label == null || (ann.label != null && ann.label + .equals(label)))) { aa.add(ann); } diff --git a/src/jalview/ext/ensembl/EnsemblRestClient.java b/src/jalview/ext/ensembl/EnsemblRestClient.java index ab3b197..5960f81 100644 --- a/src/jalview/ext/ensembl/EnsemblRestClient.java +++ b/src/jalview/ext/ensembl/EnsemblRestClient.java @@ -57,13 +57,13 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher /* * update these constants when Jalview has been checked / updated for - * changes to Ensembl REST API + * changes to Ensembl REST API (ref JAL-2105) * @see https://github.com/Ensembl/ensembl-rest/wiki/Change-log * @see http://rest.ensembl.org/info/rest?content-type=application/json */ - private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "4.8"; + private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "5.0"; - private static final String LATEST_ENSEMBL_REST_VERSION = "4.8"; + private static final String LATEST_ENSEMBL_REST_VERSION = "5.0"; private static final String REST_CHANGE_LOG = "https://github.com/Ensembl/ensembl-rest/wiki/Change-log"; @@ -513,9 +513,11 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher boolean laterVersion = StringUtils.compareVersions(version, expected) == 1; if (laterVersion) { - System.err.println(String.format( - "Expected %s REST version %s but found %s, see %s", - getDbSource(), expected, version, REST_CHANGE_LOG)); + System.err + .println(String + .format("EnsemblRestClient expected %s REST version %s but found %s, see %s", + getDbSource(), expected, version, + REST_CHANGE_LOG)); } info.restVersion = version; } catch (Throwable t) diff --git a/src/jalview/gui/AlignViewport.java b/src/jalview/gui/AlignViewport.java index d87d947..73f81bc 100644 --- a/src/jalview/gui/AlignViewport.java +++ b/src/jalview/gui/AlignViewport.java @@ -280,6 +280,8 @@ public class AlignViewport extends AlignmentViewport implements false); showGroupConsensus = Cache.getDefault("SHOW_GROUP_CONSENSUS", false); showConsensus = Cache.getDefault("SHOW_IDENTITY", true); + + showOccupancy = Cache.getDefault(Preferences.SHOW_OCCUPANCY, true); } initAutoAnnotation(); String colourProperty = alignment.isNucleotide() ? Preferences.DEFAULT_COLOUR_NUC diff --git a/src/jalview/gui/AnnotationColumnChooser.java b/src/jalview/gui/AnnotationColumnChooser.java index fa63e0d..0fe6462 100644 --- a/src/jalview/gui/AnnotationColumnChooser.java +++ b/src/jalview/gui/AnnotationColumnChooser.java @@ -110,20 +110,23 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements setAnnotations(new JComboBox(getAnnotationItems(false))); populateThresholdComboBox(threshold); - + AnnotationColumnChooser lastChooser = av + .getAnnotationColumnSelectionState(); // restore Object state from the previous session if one exists - if (av.getAnnotationColumnSelectionState() != null) + if (lastChooser != null) { - currentSearchPanel = av.getAnnotationColumnSelectionState() + currentSearchPanel = lastChooser .getCurrentSearchPanel(); - currentStructureFilterPanel = av.getAnnotationColumnSelectionState() + currentStructureFilterPanel = lastChooser .getCurrentStructureFilterPanel(); - annotations.setSelectedIndex(av.getAnnotationColumnSelectionState() + annotations.setSelectedIndex(lastChooser .getAnnotations().getSelectedIndex()); - threshold.setSelectedIndex(av.getAnnotationColumnSelectionState() + threshold.setSelectedIndex(lastChooser .getThreshold().getSelectedIndex()); - actionOption = av.getAnnotationColumnSelectionState() + actionOption = lastChooser .getActionOption(); + percentThreshold.setSelected(lastChooser.percentThreshold + .isSelected()); } try @@ -151,6 +154,9 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements thresholdPanel.setFont(JvSwingUtils.getLabelFont()); thresholdPanel.setLayout(new MigLayout("", "[left][right]", "[][]")); + percentThreshold.setBackground(Color.white); + percentThreshold.setFont(JvSwingUtils.getLabelFont()); + JPanel actionPanel = new JPanel(); actionPanel.setBackground(Color.white); actionPanel.setFont(JvSwingUtils.getLabelFont()); @@ -174,8 +180,9 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements ngStructureFilterPanel = new StructureFilterPanel(this); thresholdPanel.add(getThreshold()); - thresholdPanel.add(thresholdValue, "wrap"); - thresholdPanel.add(slider, "grow, span, wrap"); + thresholdPanel.add(percentThreshold, "wrap"); + thresholdPanel.add(slider, "grow"); + thresholdPanel.add(thresholdValue, "span, wrap"); actionPanel.add(ok); actionPanel.add(cancel); @@ -282,12 +289,14 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements slider.setEnabled(true); thresholdValue.setEnabled(true); + percentThreshold.setEnabled(true); if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD) { slider.setEnabled(false); thresholdValue.setEnabled(false); thresholdValue.setText(""); + percentThreshold.setEnabled(false); // build filter params } else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD) @@ -308,7 +317,9 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements slider.setMinimum((int) (getCurrentAnnotation().graphMin * 1000)); slider.setMaximum((int) (getCurrentAnnotation().graphMax * 1000)); slider.setValue((int) (getCurrentAnnotation().threshold.value * 1000)); - thresholdValue.setText(getCurrentAnnotation().threshold.value + ""); + + setThresholdValueText(); + slider.setMajorTickSpacing((int) (range / 10f)); slider.setEnabled(true); thresholdValue.setEnabled(true); diff --git a/src/jalview/gui/AnnotationRowFilter.java b/src/jalview/gui/AnnotationRowFilter.java index c2bf41b..a3ce528 100644 --- a/src/jalview/gui/AnnotationRowFilter.java +++ b/src/jalview/gui/AnnotationRowFilter.java @@ -62,6 +62,8 @@ public abstract class AnnotationRowFilter extends JPanel protected JCheckBox seqAssociated = new JCheckBox(); + protected JCheckBox percentThreshold = new JCheckBox(); + protected JSlider slider = new JSlider(); protected JTextField thresholdValue = new JTextField(20); @@ -120,13 +122,32 @@ public abstract class AnnotationRowFilter extends JPanel { if (!adjusting) { - thresholdValue.setText((slider.getValue() / 1000f) + ""); + setThresholdValueText(); valueChanged(!sliderDragging); } } }); } + /** + * update the text field from the threshold slider. preserves state of + * 'adjusting' so safe to call in init. + */ + protected void setThresholdValueText() + { + boolean oldadj = adjusting; + adjusting = true; + if (percentThreshold.isSelected()) + { + thresholdValue.setText("" + (slider.getValue() - slider.getMinimum()) + * 100f / (slider.getMaximum() - slider.getMinimum())); + } + else + { + thresholdValue.setText((slider.getValue() / 1000f) + ""); + } + adjusting = oldadj; + } protected void addSliderMouseListeners() { @@ -275,13 +296,27 @@ public abstract class AnnotationRowFilter extends JPanel try { float f = Float.parseFloat(thresholdValue.getText()); - slider.setValue((int) (f * 1000)); + if (percentThreshold.isSelected()) + { + slider.setValue(slider.getMinimum() + + ((int) ((f / 100f) * (slider.getMaximum() - slider + .getMinimum())))); + } + else + { + slider.setValue((int) (f * 1000)); + } updateView(); } catch (NumberFormatException ex) { } } + protected void percentageValue_actionPerformed() + { + setThresholdValueText(); + } + protected void thresholdIsMin_actionPerformed() { updateView(); @@ -439,6 +474,18 @@ public abstract class AnnotationRowFilter extends JPanel } }); + percentThreshold.setText(MessageManager.getString("label.as_percentage")); + percentThreshold.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + if (!adjusting) + { + percentageValue_actionPerformed(); + } + } + }); slider.setPaintLabels(false); slider.setPaintTicks(true); slider.setBackground(Color.white); diff --git a/src/jalview/gui/Preferences.java b/src/jalview/gui/Preferences.java index cf80a6d..cccdd2e 100755 --- a/src/jalview/gui/Preferences.java +++ b/src/jalview/gui/Preferences.java @@ -107,6 +107,8 @@ public class Preferences extends GPreferences public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE"; + public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY"; + private static final int MIN_FONT_SIZE = 1; private static final int MAX_FONT_SIZE = 30; @@ -210,6 +212,7 @@ public class Preferences extends GPreferences openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false)); showUnconserved .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false)); + showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false)); showGroupConsensus.setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false)); showGroupConservation.setSelected(Cache.getDefault( @@ -572,6 +575,8 @@ public class Preferences extends GPreferences Boolean.toString(idItalics.isSelected())); Cache.applicationProperties.setProperty("SHOW_UNCONSERVED", Boolean.toString(showUnconserved.isSelected())); + Cache.applicationProperties.setProperty(SHOW_OCCUPANCY, + Boolean.toString(showOccupancy.isSelected())); Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS", Boolean.toString(showGroupConsensus.isSelected())); Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION", @@ -851,6 +856,7 @@ public class Preferences extends GPreferences conservation.setEnabled(annotations.isSelected()); quality.setEnabled(annotations.isSelected()); identity.setEnabled(annotations.isSelected()); + showOccupancy.setEnabled(annotations.isSelected()); showGroupConsensus.setEnabled(annotations.isSelected()); showGroupConservation.setEnabled(annotations.isSelected()); showConsensHistogram.setEnabled(annotations.isSelected() diff --git a/src/jalview/io/AnnotationFile.java b/src/jalview/io/AnnotationFile.java index 31aeffa..e685627 100755 --- a/src/jalview/io/AnnotationFile.java +++ b/src/jalview/io/AnnotationFile.java @@ -110,23 +110,22 @@ public class AnnotationFile */ public class ViewDef { - public String viewname; + // TODO this class is not used - remove? + public final String viewname; - public HiddenSequences hidseqs; + public final HiddenSequences hidseqs; - public HiddenColumns hiddencols; + public final HiddenColumns hiddencols; - public Vector visibleGroups; + public final Hashtable hiddenRepSeqs; - public Hashtable hiddenRepSeqs; - - public ViewDef(String viewname, HiddenSequences hidseqs, - HiddenColumns hiddencols, Hashtable hiddenRepSeqs) + public ViewDef(String vname, HiddenSequences hseqs, + HiddenColumns hcols, Hashtable hRepSeqs) { - this.viewname = viewname; - this.hidseqs = hidseqs; - this.hiddencols = hiddencols; - this.hiddenRepSeqs = hiddenRepSeqs; + this.viewname = vname; + this.hidseqs = hseqs; + this.hiddencols = hcols; + this.hiddenRepSeqs = hRepSeqs; } } @@ -153,7 +152,7 @@ public class AnnotationFile } if (list == null) { - list = view.visibleGroups; + // list = view.visibleGroups; } if (cs == null) { @@ -538,7 +537,7 @@ public class AnnotationFile return false; } - public void printGroups(List list) + protected void printGroups(List list) { SequenceI seqrep = null; for (SequenceGroup sg : list) @@ -584,7 +583,8 @@ public class AnnotationFile if (sg.cs != null) { text.append("colour="); - text.append(sg.cs.toString()); + text.append(ColourSchemeProperty.getColourName(sg.cs + .getColourScheme())); text.append("\t"); if (sg.cs.getThreshold() != 0) { diff --git a/src/jalview/io/JSONFile.java b/src/jalview/io/JSONFile.java index d6be51c..93a0167 100644 --- a/src/jalview/io/JSONFile.java +++ b/src/jalview/io/JSONFile.java @@ -47,6 +47,7 @@ import jalview.json.binding.biojson.v1.SequenceFeaturesPojo; import jalview.json.binding.biojson.v1.SequenceGrpPojo; import jalview.json.binding.biojson.v1.SequencePojo; import jalview.renderer.seqfeatures.FeatureColourFinder; +import jalview.schemes.ColourSchemeProperty; import jalview.schemes.JalviewColourScheme; import jalview.schemes.ResidueColourScheme; import jalview.util.ColorUtils; @@ -238,8 +239,8 @@ public class JSONFile extends AlignFile implements ComplexAlignFile { SequenceGrpPojo seqGrpPojo = new SequenceGrpPojo(); seqGrpPojo.setGroupName(seqGrp.getName()); - seqGrpPojo.setColourScheme(seqGrp.getColourScheme() - .getSchemeName()); + seqGrpPojo.setColourScheme(ColourSchemeProperty + .getColourName(seqGrp.getColourScheme())); seqGrpPojo.setColourText(seqGrp.getColourText()); seqGrpPojo.setDescription(seqGrp.getDescription()); seqGrpPojo.setDisplayBoxes(seqGrp.getDisplayBoxes()); @@ -766,8 +767,8 @@ public class JSONFile extends AlignFile implements ComplexAlignFile } } } - globalColourScheme = (viewport.getGlobalColourScheme() == null) ? ResidueColourScheme.NONE - : viewport.getGlobalColourScheme().getSchemeName(); + globalColourScheme = ColourSchemeProperty.getColourName(viewport + .getGlobalColourScheme()); setDisplayedFeatures(viewport.getFeaturesDisplayed()); showSeqFeatures = viewport.isShowSequenceFeatures(); diff --git a/src/jalview/jbgui/GPreferences.java b/src/jalview/jbgui/GPreferences.java index dda06b4..1ad95dd 100755 --- a/src/jalview/jbgui/GPreferences.java +++ b/src/jalview/jbgui/GPreferences.java @@ -101,6 +101,8 @@ public class GPreferences extends JPanel protected JComboBox fontNameCB = new JComboBox(); + protected JCheckBox showOccupancy = new JCheckBox(); + protected JCheckBox showUnconserved = new JCheckBox(); protected JCheckBox idItalics = new JCheckBox(); @@ -1174,6 +1176,13 @@ public class GPreferences extends JPanel identity.setHorizontalTextPosition(SwingConstants.LEFT); identity.setSelected(true); identity.setText(MessageManager.getString("label.consensus")); + showOccupancy.setFont(LABEL_FONT); + showOccupancy.setEnabled(false); + showOccupancy.setHorizontalAlignment(SwingConstants.RIGHT); + showOccupancy.setHorizontalTextPosition(SwingConstants.LEFT); + showOccupancy.setSelected(true); + showOccupancy.setText(MessageManager.getString("label.occupancy")); + JLabel showGroupbits = new JLabel(); showGroupbits.setFont(LABEL_FONT); showGroupbits.setHorizontalAlignment(SwingConstants.RIGHT); @@ -1228,10 +1237,10 @@ public class GPreferences extends JPanel .getString("label.database_references")); annotations.setFont(LABEL_FONT); annotations.setHorizontalAlignment(SwingConstants.RIGHT); - annotations.setHorizontalTextPosition(SwingConstants.LEADING); + annotations.setHorizontalTextPosition(SwingConstants.LEFT); annotations.setSelected(true); annotations.setText(MessageManager.getString("label.show_annotations")); - annotations.setBounds(new Rectangle(169, 12, 200, 23)); + // annotations.setBounds(new Rectangle(169, 12, 200, 23)); annotations.addActionListener(new ActionListener() { @Override @@ -1358,11 +1367,13 @@ public class GPreferences extends JPanel sortAutocalc.setBounds(new Rectangle(290, 285, 165, 21)); JPanel annsettingsPanel = new JPanel(); - annsettingsPanel.setBounds(new Rectangle(173, 34, 320, 75)); + annsettingsPanel.setBounds(new Rectangle(173, 13, 320, 96)); annsettingsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); annsettingsPanel.setBorder(new EtchedBorder()); visualTab.add(annsettingsPanel); Border jb = new EmptyBorder(1, 1, 4, 5); + annotations.setBorder(jb); + showOccupancy.setBorder(jb); quality.setBorder(jb); conservation.setBorder(jb); identity.setBorder(jb); @@ -1374,17 +1385,26 @@ public class GPreferences extends JPanel showConsensLogo.setBorder(jb); JPanel autoAnnotSettings = new JPanel(); - autoAnnotSettings.setLayout(new GridLayout(3, 3)); annsettingsPanel.add(autoAnnotSettings); + autoAnnotSettings.setLayout(new GridLayout(0, 2)); + autoAnnotSettings.add(annotations); autoAnnotSettings.add(quality); + // second row of autoannotation box + autoAnnotSettings = new JPanel(); + annsettingsPanel.add(autoAnnotSettings); + + autoAnnotSettings.setLayout(new GridLayout(0, 3)); autoAnnotSettings.add(conservation); autoAnnotSettings.add(identity); + autoAnnotSettings.add(showOccupancy); autoAnnotSettings.add(showGroupbits); autoAnnotSettings.add(showGroupConservation); autoAnnotSettings.add(showGroupConsensus); autoAnnotSettings.add(showConsensbits); autoAnnotSettings.add(showConsensHistogram); autoAnnotSettings.add(showConsensLogo); + + JPanel tooltipSettings = new JPanel(); tooltipSettings.setBorder(new TitledBorder(MessageManager @@ -1433,7 +1453,6 @@ public class GPreferences extends JPanel jPanel2.add(sortAnnLabel); jPanel2.add(startupCheckbox); visualTab.add(jPanel2); - visualTab.add(annotations); visualTab.add(startupFileTextfield); visualTab.add(sortby); visualTab.add(sortAnnBy); diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index 9c8c233..6a38f21 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -52,6 +52,7 @@ import jalview.structure.VamsasSource; import jalview.util.Comparison; import jalview.util.MapList; import jalview.util.MappingUtils; +import jalview.util.MessageManager; import jalview.viewmodel.styles.ViewStyle; import jalview.workers.AlignCalcManager; import jalview.workers.ComplementConsensusThread; @@ -824,7 +825,7 @@ public abstract class AlignmentViewport implements AlignViewportI, public void updateConsensus(final AlignmentViewPanel ap) { // see note in mantis : issue number 8585 - if ((consensus == null || gapcounts == null) || !autoCalculateConsensus) + if (consensus == null || !autoCalculateConsensus) { return; } @@ -1287,6 +1288,8 @@ public abstract class AlignmentViewport implements AlignViewportI, protected boolean showConsensus = true; + protected boolean showOccupancy = true; + private Map sequenceColours = new HashMap(); protected SequenceAnnotationOrder sortAnnotationsBy = null; @@ -1899,14 +1902,11 @@ public abstract class AlignmentViewport implements AlignViewportI, { initRNAStructure(); } - consensus = new AlignmentAnnotation("Consensus", "PID", + consensus = new AlignmentAnnotation("Consensus", + MessageManager.getString("label.consensus_descr"), new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); initConsensus(consensus); - gapcounts = new AlignmentAnnotation("Occupancy", - "Number of aligned positions", - new Annotation[1], 0f, alignment.getHeight(), - AlignmentAnnotation.BAR_GRAPH); - initGapCounts(gapcounts); + initGapCounts(); initComplementConsensus(); } @@ -1940,7 +1940,9 @@ public abstract class AlignmentViewport implements AlignViewportI, if (doConsensus) { complementConsensus = new AlignmentAnnotation("cDNA Consensus", - "PID for cDNA", new Annotation[1], 0f, 100f, + MessageManager + .getString("label.complement_consensus_descr"), + new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); initConsensus(complementConsensus); return true; @@ -1963,15 +1965,20 @@ public abstract class AlignmentViewport implements AlignViewportI, // these should be extracted from the view model - style and settings for // derived annotation - private void initGapCounts(AlignmentAnnotation counts) + private void initGapCounts() { - counts.hasText = false; - counts.autoCalculated = true; - counts.graph = AlignmentAnnotation.BAR_GRAPH; - - if (showConsensus) + if (showOccupancy) { - alignment.addAnnotation(counts); + gapcounts = new AlignmentAnnotation("Occupancy", + MessageManager.getString("label.occupancy_descr"), + new Annotation[1], 0f, + alignment.getHeight(), AlignmentAnnotation.BAR_GRAPH); + gapcounts.hasText = true; + gapcounts.autoCalculated = true; + gapcounts.scaleColLabel = true; + gapcounts.graph = AlignmentAnnotation.BAR_GRAPH; + + alignment.addAnnotation(gapcounts); } } @@ -1982,8 +1989,8 @@ public abstract class AlignmentViewport implements AlignViewportI, if (conservation == null) { conservation = new AlignmentAnnotation("Conservation", - "Conservation of total alignment less than " - + getConsPercGaps() + "% gaps", new Annotation[1], + MessageManager.formatMessage("label.conservation_descr", + getConsPercGaps()), new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); conservation.hasText = true; conservation.autoCalculated = true; @@ -1999,7 +2006,7 @@ public abstract class AlignmentViewport implements AlignViewportI, if (quality == null) { quality = new AlignmentAnnotation("Quality", - "Alignment Quality based on Blosum62 scores", + MessageManager.getString("label.quality_descr"), new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); quality.hasText = true; quality.autoCalculated = true; @@ -2012,7 +2019,8 @@ public abstract class AlignmentViewport implements AlignViewportI, { if (alignment.hasRNAStructure() && strucConsensus == null) { - strucConsensus = new AlignmentAnnotation("StrucConsensus", "PID", + strucConsensus = new AlignmentAnnotation("StrucConsensus", + MessageManager.getString("label.strucconsensus_descr"), new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); strucConsensus.hasText = true; strucConsensus.autoCalculated = true; diff --git a/src/jalview/ws/sifts/SiftsClient.java b/src/jalview/ws/sifts/SiftsClient.java index c69581f..fe3a25b 100644 --- a/src/jalview/ws/sifts/SiftsClient.java +++ b/src/jalview/ws/sifts/SiftsClient.java @@ -575,18 +575,8 @@ public class SiftsClient implements SiftsClientI .equalsIgnoreCase(seqCoordSys.getName()) && isAccessionMatched(cRefDb.getDbAccessionId())) { - String resNumIndexString = cRefDb.getDbResNum() - .equalsIgnoreCase("None") ? String.valueOf(UNASSIGNED) - : cRefDb.getDbResNum(); - try - { - currSeqIndex = Integer.valueOf(resNumIndexString); - } catch (NumberFormatException nfe) - { - currSeqIndex = Integer.valueOf(resNumIndexString - .split("[a-zA-Z]")[0]); - continue; - } + currSeqIndex = getLeadingIntegerValue( + cRefDb.getDbResNum(), UNASSIGNED); if (pdbRefDb != null) { break;// exit loop if pdb and uniprot are already found @@ -599,23 +589,11 @@ public class SiftsClient implements SiftsClientI } if (currSeqIndex >= seq.getStart() && currSeqIndex <= seq.getEnd()) { - int resNum; - try - { - resNum = (pdbRefDb == null) ? Integer.valueOf(residue - .getDbResNum()) : Integer.valueOf(pdbRefDb - .getDbResNum()); - } catch (NumberFormatException nfe) - { - if (pdbRefDb == null || pdbRefDb.getDbResNum().equals("null")) - { - resNum = UNASSIGNED; - continue; - } - resNum = Integer.valueOf(pdbRefDb - .getDbResNum().split("[a-zA-Z]")[0]); - continue; - } + + int resNum = (pdbRefDb == null) ? getLeadingIntegerValue( + residue.getDbResNum(), UNASSIGNED) + : getLeadingIntegerValue(pdbRefDb.getDbResNum(), + UNASSIGNED); if (isResidueObserved(residue) || seqCoordSys == CoordinateSys.UNIPROT) @@ -638,6 +616,30 @@ public class SiftsClient implements SiftsClientI } /** + * Get the leading integer part of a string that begins with an integer. + * + * @param input + * - the string input to process + * @param failValue + * - value returned if unsuccessful + * @return + */ + static int getLeadingIntegerValue(String input, int failValue) + { + if (input == null) + { + return failValue; + } + String[] parts = input.split("(?=\\D)(?<=\\d)"); + if (parts != null && parts.length > 0 && parts[0].matches("[0-9]+")) + { + return Integer.valueOf(parts[0]); + } + return failValue; + } + + + /** * * @param chainId * Target chain to populate mapping of its atom positions. diff --git a/test/jalview/datamodel/AlignmentTest.java b/test/jalview/datamodel/AlignmentTest.java index c5d09c1..660a69c 100644 --- a/test/jalview/datamodel/AlignmentTest.java +++ b/test/jalview/datamodel/AlignmentTest.java @@ -620,6 +620,67 @@ public class AlignmentTest assertFalse(iter.hasNext()); } + /** + * Test method that returns annotations that match on reference sequence, + * label, or calcId. + */ + @Test(groups = { "Functional" }) + public void testFindAnnotations_bySeqLabelandorCalcId() + { + // TODO: finish testFindAnnotations_bySeqLabelandorCalcId test + /* Note - this is an incomplete test - need to check null or + * non-null [ matches, not matches ] behaviour for each of the three + * parameters..*/ + + // search for a single, unique calcId with wildcards on other params + Iterable anns = al.findAnnotations(null, + "CalcIdForD.melanogaster.2", null); + Iterator iter = anns.iterator(); + assertTrue(iter.hasNext()); + AlignmentAnnotation ann = iter.next(); + assertEquals("D.melanogaster.2", ann.sequenceRef.getName()); + assertFalse(iter.hasNext()); + + // save reference to test sequence reference parameter + SequenceI rseq = ann.sequenceRef; + + // search for annotation associated with a single sequence + anns = al.findAnnotations(rseq, null, null); + iter = anns.iterator(); + assertTrue(iter.hasNext()); + ann = iter.next(); + assertEquals("D.melanogaster.2", ann.sequenceRef.getName()); + assertFalse(iter.hasNext()); + + // search for annotation with a non-existant calcId + anns = al.findAnnotations(null, "CalcIdForD.melanogaster.?", null); + iter = anns.iterator(); + assertFalse(iter.hasNext()); + + // search for annotation with a particular label - expect three + anns = al.findAnnotations(null, null, "secondary structure"); + iter = anns.iterator(); + assertTrue(iter.hasNext()); + iter.next(); + assertTrue(iter.hasNext()); + iter.next(); + assertTrue(iter.hasNext()); + iter.next(); + // third found.. so + assertFalse(iter.hasNext()); + + // null on all parameters == find all annotations + anns = al.findAnnotations(null, null, null); + iter = anns.iterator(); + int n = al.getAlignmentAnnotation().length; + while (iter.hasNext()) + { + n--; + iter.next(); + } + assertTrue("Found " + n + " fewer annotations from search.", n == 0); + } + @Test(groups = { "Functional" }) public void testDeleteAllAnnotations_includingAutocalculated() { diff --git a/test/jalview/datamodel/AlignmentViewTest.java b/test/jalview/datamodel/AlignmentViewTest.java index 594d6e6..b201c7e 100644 --- a/test/jalview/datamodel/AlignmentViewTest.java +++ b/test/jalview/datamodel/AlignmentViewTest.java @@ -22,7 +22,11 @@ package jalview.datamodel; import static org.testng.Assert.assertEquals; +import jalview.gui.AlignFrame; +import jalview.gui.AlignViewport; import jalview.gui.JvOptionPane; +import jalview.io.DataSourceType; +import jalview.io.FileLoader; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -50,4 +54,69 @@ public class AlignmentViewTest assertEquals(av.getVisibleAlignment('$').getSequenceAt(0) .getSequenceAsString(), "A$$CDE"); } + + @Test(groups = { "Functional" }) + public void testGetVisibleContigs() + { + AlignFrame af = new FileLoader().LoadFileWaitTillLoaded( + ">s1\n0123456789\n", DataSourceType.PASTE); + AlignViewport av = af.getViewport(); + AlignmentView view = av.getAlignmentView(true); + + /* + * verify getVisibleContigs returns inclusive [start, end] ranges + * + * no columns hidden + */ + int[] contigs = view.getVisibleContigs(); + assertEquals(contigs, new int[] { 0, 9 }); + + /* + * hide 3 internal columns + */ + av.hideColumns(5, 7); + // the old AlignmentView is now stale! + contigs = view.getVisibleContigs(); + assertEquals(contigs, new int[] { 0, 9 }); + // get a fresh AlignmentView + view = av.getAlignmentView(true); + contigs = view.getVisibleContigs(); + assertEquals(contigs, new int[] { 0, 4, 8, 9 }); + + // hide first 2 columns + av.hideColumns(0, 1); + view = av.getAlignmentView(true); + contigs = view.getVisibleContigs(); + assertEquals(contigs, new int[] { 2, 4, 8, 9 }); + + // hide last column + av.hideColumns(9, 9); + view = av.getAlignmentView(true); + contigs = view.getVisibleContigs(); + assertEquals(contigs, new int[] { 2, 4, 8, 8 }); + + // unhide columns 5-7 + av.showColumn(5); + view = av.getAlignmentView(true); + contigs = view.getVisibleContigs(); + assertEquals(contigs, new int[] { 2, 8 }); + + // hide columns 2-7 + av.hideColumns(2, 7); + view = av.getAlignmentView(true); + contigs = view.getVisibleContigs(); + assertEquals(contigs, new int[] { 8, 8 }); + + // hide column 8 + av.hideColumns(8, 8); + view = av.getAlignmentView(true); + contigs = view.getVisibleContigs(); + assertEquals(contigs, new int[] {}); + + // unhide all + av.showAllHiddenColumns(); + view = av.getAlignmentView(true); + contigs = view.getVisibleContigs(); + assertEquals(contigs, new int[] { 0, 9 }); + } } diff --git a/test/jalview/gui/AlignViewportTest.java b/test/jalview/gui/AlignViewportTest.java index 06df70a..e6c16b7 100644 --- a/test/jalview/gui/AlignViewportTest.java +++ b/test/jalview/gui/AlignViewportTest.java @@ -50,6 +50,7 @@ import jalview.util.MapList; import java.util.ArrayList; import java.util.List; +import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -327,6 +328,8 @@ public class AlignViewportTest Boolean.TRUE.toString()); Cache.applicationProperties.setProperty("SHOW_CONSERVATION", Boolean.FALSE.toString()); + Cache.applicationProperties.setProperty("SHOW_OCCUPANCY", + Boolean.FALSE.toString()); Cache.applicationProperties.setProperty("SHOW_IDENTITY", Boolean.FALSE.toString()); AlignFrame af = new FileLoader().LoadFileWaitTillLoaded( @@ -404,4 +407,40 @@ public class AlignViewportTest av.setSelectionGroup(sg2); assertSame(sg2.getContext(), sg1); // unchanged } + /** + * Verify that setting/clearing SHOW_OCCUPANCY preference adds or omits occupancy row from viewport + */ + @Test(groups = { "Functional" }) + public void testShowOrDontShowOccupancy() + { + // disable occupancy + jalview.bin.Cache.setProperty("SHOW_OCCUPANCY", Boolean.FALSE.toString()); + AlignFrame af = new FileLoader().LoadFileWaitTillLoaded( + "examples/uniref50.fa", DataSourceType.FILE); + AlignViewport av = af.getViewport(); + Assert.assertNull(av.getAlignmentGapAnnotation(), "Preference did not disable occupancy row."); + int c = 0; + for (AlignmentAnnotation aa : av.getAlignment().findAnnotations(null, + null, "Occupancy")) + { + c++; + } + Assert.assertEquals(c, 0, "Expected zero occupancy rows."); + + // enable occupancy + jalview.bin.Cache.setProperty("SHOW_OCCUPANCY", Boolean.TRUE.toString()); + af = new FileLoader().LoadFileWaitTillLoaded( + "examples/uniref50.fa", DataSourceType.FILE); + av = af.getViewport(); + Assert.assertNotNull(av.getAlignmentGapAnnotation(), "Preference did not enable occupancy row."); + c = 0; + for (AlignmentAnnotation aa : av.getAlignment().findAnnotations(null, + null, av.getAlignmentGapAnnotation().label)) + { + c++; + } + ; + Assert.assertEquals(c, 1, "Expected to find one occupancy row."); + + } } diff --git a/test/jalview/gui/StructureChooserTest.java b/test/jalview/gui/StructureChooserTest.java index b7eef0f..c04353f 100644 --- a/test/jalview/gui/StructureChooserTest.java +++ b/test/jalview/gui/StructureChooserTest.java @@ -136,7 +136,7 @@ public class StructureChooserTest assertEquals("Cached PDB Entries", filterOpt.getName()); } - @Test(groups = { "Functional" }) + @Test(groups = { "Network" }) public void fetchStructuresInfoTest() { SequenceI[] selectedSeqs = new SequenceI[] { seq }; diff --git a/test/jalview/io/AnnotationFileIOTest.java b/test/jalview/io/AnnotationFileIOTest.java index c3a1801..105f6e4 100644 --- a/test/jalview/io/AnnotationFileIOTest.java +++ b/test/jalview/io/AnnotationFileIOTest.java @@ -124,6 +124,7 @@ public class AnnotationFileIOTest DataSourceType.FILE)); AnnotationFile aff = new AnnotationFile(); + // ViewDef is not used by Jalview ViewDef v = aff.new ViewDef(null, al.getHiddenSequences(), cs, new Hashtable()); String anfileout = new AnnotationFile().printAnnotations( diff --git a/test/jalview/io/JSONFileTest.java b/test/jalview/io/JSONFileTest.java index 6ccbd5d..3b418ec 100644 --- a/test/jalview/io/JSONFileTest.java +++ b/test/jalview/io/JSONFileTest.java @@ -130,13 +130,14 @@ public class JSONFileTest expectedSeqs.put(seq.getName(), seq); } - // create and add sequence groups - ArrayList grpSeqs = new ArrayList(); + // create and add a sequence group + List grpSeqs = new ArrayList(); grpSeqs.add(seqs[1]); grpSeqs.add(seqs[2]); grpSeqs.add(seqs[3]); grpSeqs.add(seqs[4]); - SequenceGroup seqGrp = new SequenceGroup(grpSeqs, "JGroup:1883305585", + SequenceGroup seqGrp = new SequenceGroup(grpSeqs, + "JGroup:1883305585", null, true, true, false, 21, 29); ColourSchemeI scheme = ColourSchemeMapper.getJalviewColourScheme( "zappo", seqGrp); @@ -340,11 +341,12 @@ public class JSONFileTest "Zappo colour scheme expected!"); } - @Test(groups = { "Functional" }) /** - * Test for bug JAL-2489, NPE when exporting BioJSON with global colour scheme set as 'None' + * Test for bug JAL-2489, NPE when exporting BioJSON with global colour + * scheme, and a group colour scheme, set as 'None' */ - public void testBioJSONRoundTripWithGlobalColourSchemeSetAsNone() + @Test(groups = { "Functional" }) + public void testBioJSONRoundTripWithColourSchemeNone() { AppletFormatAdapter formatAdapter = new AppletFormatAdapter(); @@ -359,7 +361,14 @@ public class JSONFileTest bioJsonFile.getHiddenSequences(), bioJsonFile.getHiddenColumns(), AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); - // Change colour scheme to 'None' and perform round trip + + /* + * Create a group on the alignment; + * Change global and group colour scheme to 'None' and perform round trip + */ + SequenceGroup sg = new SequenceGroup(); + sg.addSequence(_alignment.getSequenceAt(0), false); + sg.setColourScheme(null); ColourSchemeI cs = ColourSchemeMapper.getJalviewColourScheme( ResidueColourScheme.NONE, _alignment); alignFrame.changeColour(cs); @@ -556,4 +565,47 @@ public class JSONFileTest // System.out.println(">>>>>>>>>>>>>> features matched : " + matched); return matched; } + + /** + * Test group roundtrip with null (None) group colour scheme + * + * @throws IOException + */ + @Test(groups = { "Functional" }) + public void testGrpParsed_colourNone() throws IOException + { + AlignmentI copy = new Alignment(testAlignment); + SequenceGroup sg = testAlignment.getGroups().get(0); + SequenceGroup copySg = new SequenceGroup(new ArrayList(), + sg.getName(), + null, sg.getDisplayBoxes(), sg.getDisplayText(), + sg.getColourText(), sg.getStartRes(), sg.getEndRes()); + for (SequenceI seq : sg.getSequences()) + { + int seqIndex = testAlignment.findIndex(seq); + copySg.addSequence(copy.getSequenceAt(seqIndex), false); + } + copy.addGroup(copySg); + + AlignFrame af = new AlignFrame(copy, copy.getWidth(), copy.getHeight()); + AppletFormatAdapter formatAdapter = new AppletFormatAdapter( + af.alignPanel); + String jsonOutput = formatAdapter.formatSequences(FileFormat.Json, + copy, false); + formatAdapter = new AppletFormatAdapter(); + AlignmentI newAlignment = formatAdapter.readFile(jsonOutput, + DataSourceType.PASTE, FileFormat.Json); + + Assert.assertNotNull(newAlignment.getGroups()); + for (SequenceGroup seqGrp : newAlignment.getGroups()) + { + SequenceGroup expectedGrp = expectedGrps.get(seqGrp.getName()); + AssertJUnit.assertTrue( + "Failed SequenceGroup Test for >>> " + seqGrp.getName(), + isGroupMatched(expectedGrp, seqGrp)); + passedCount++; + } + AssertJUnit.assertEquals("Some SequenceGroups did not pass the test", + TEST_GRP_HEIGHT, passedCount); + } } diff --git a/test/jalview/io/testProps.jvprops b/test/jalview/io/testProps.jvprops index 95da22e..8ede59c 100644 --- a/test/jalview/io/testProps.jvprops +++ b/test/jalview/io/testProps.jvprops @@ -31,6 +31,7 @@ JAVA_CONSOLE_SCREEN_HEIGHT=162 PIR_MODELLER=false GAP_SYMBOL=- SHOW_QUALITY=true +SHOW_OCCUPANCY=true SHOW_GROUP_CONSERVATION=false SHOW_JWS2_SERVICES=true SHOW_NPFEATS_TOOLTIP=true diff --git a/test/jalview/ws/dbsources/RemoteFormatTest.java b/test/jalview/ws/dbsources/RemoteFormatTest.java new file mode 100644 index 0000000..90d4472 --- /dev/null +++ b/test/jalview/ws/dbsources/RemoteFormatTest.java @@ -0,0 +1,121 @@ +package jalview.ws.dbsources; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import jalview.analysis.AlignSeq; +import jalview.bin.Cache; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.DBRefSource; +import jalview.datamodel.SequenceI; +import jalview.ext.ensembl.EnsemblGenomes; +import jalview.fts.api.FTSData; +import jalview.fts.api.FTSDataColumnI; +import jalview.fts.api.FTSRestClientI; +import jalview.fts.core.FTSRestRequest; +import jalview.fts.core.FTSRestResponse; +import jalview.fts.service.uniprot.UniProtFTSRestClient; +import jalview.ws.SequenceFetcher; +import jalview.ws.seqfetcher.DbSourceProxy; + +import java.util.ArrayList; +import java.util.List; + +import org.testng.annotations.BeforeTest; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * A class to verify that remotely fetched data has an expected format and can + * be successfully processed by Jalview. This is intended as a first line of + * defence and early warning of service affecting changes to data fetched + * externally. + *

+ * This is class is not intended to cover remote services e.g. alignment. Nor + * should it duplicate tests already provided by other classes (such as + * PDBFTSRestClientTest). Or maybe we will relocate those tests here... + */ +public class RemoteFormatTest +{ + SequenceFetcher sf; + + @BeforeTest(alwaysRun = true) + public void setUp() throws Exception + { + Cache.loadProperties("test/jalview/io/testProps.jvprops"); + // ensure 'add annotation from structure' is selected + Cache.applicationProperties.setProperty("STRUCT_FROM_PDB", + Boolean.TRUE.toString()); + Cache.applicationProperties.setProperty("ADD_SS_ANN", + Boolean.TRUE.toString()); + + sf = new SequenceFetcher(false); + } + + @DataProvider(name = "AccessionData") + protected Object[][] getAccessions() + { + return new Object[][] { { DBRefSource.UNIPROT, "P30419" }, + { DBRefSource.PDB, "1QIP" }, { DBRefSource.EMBL, "X53828" }, + { DBRefSource.EMBLCDS, "CAA37824" }, + { DBRefSource.ENSEMBL, "ENSG00000157764" }, + { new EnsemblGenomes().getDbSource(), "DDB_G0283883" }, + { new PfamFull().getDbSource(), "PF03760" }, + { new PfamSeed().getDbSource(), "PF03760" }, + { new RfamSeed().getDbSource(), "RF00014" } }; + } + + @Test(groups = "Network", dataProvider = "AccessionData") + public void testFetchAccession(String dbSource, String accessionId) + throws Exception + { + System.out.println("Fetching " + accessionId + " from " + dbSource); + List sps = sf.getSourceProxy(dbSource); + assertFalse(sps.isEmpty()); + AlignmentI al = sps.get(0).getSequenceRecords(accessionId); + assertNotNull(al); + assertTrue(al.getHeight() > 0); + SequenceI sq = al.getSequenceAt(0); + // suppress this check as only Uniprot and PDB acquire PDB refs + // assertTrue(sq.getAllPDBEntries().size() > 0, "No PDBEntry on sequence."); + assertTrue(sq.getDBRefs().length > 0, "No DBRef on sequence."); + // suppress this test as only certain databases provide 'primary' dbrefs + // assertFalse(sq.getPrimaryDBRefs().isEmpty()); + int length = AlignSeq.extractGaps("-. ", sq.getSequenceAsString()) + .length(); + assertEquals(sq.getEnd() - sq.getStart() + 1, length, + "Sequence start/end doesn't match number of residues in sequence"); + } + + @Test(groups = { "Network" }) + public void testUniprotFreeTextSearch() throws Exception + { + List wantedFields = new ArrayList(); + FTSRestClientI client = UniProtFTSRestClient.getInstance(); + wantedFields.add(client.getDataColumnByNameOrCode("id")); + wantedFields.add(client.getDataColumnByNameOrCode("entry name")); + wantedFields.add(client.getDataColumnByNameOrCode("organism")); + wantedFields.add(client.getDataColumnByNameOrCode("reviewed")); // Status + wantedFields.add(client.getDataColumnByNameOrCode("length")); + + FTSRestRequest request = new FTSRestRequest(); + request.setAllowEmptySeq(false); + request.setResponseSize(100); + request.setFieldToSearchBy("Search All"); + request.setSearchTerm("metanephrops"); // lobster! + request.setWantedFields(wantedFields); + + FTSRestResponse response; + response = client.executeRequest(request); + assertTrue(response.getNumberOfItemsFound() > 20); + assertTrue(response.getSearchSummary() != null); + assertTrue(response.getSearchSummary().size() > 20); + // verify we successfully filtered out the header row (JAL-2485) + FTSData header = response.getSearchSummary().iterator().next(); + assertFalse( + header.getSummaryData()[0].toString().equalsIgnoreCase("Entry"), + "Failed to filter out summary header row"); + } +} diff --git a/test/jalview/ws/jws2/ParameterUtilsTest.java b/test/jalview/ws/jws2/ParameterUtilsTest.java index e859cb0..c0aa2ee 100644 --- a/test/jalview/ws/jws2/ParameterUtilsTest.java +++ b/test/jalview/ws/jws2/ParameterUtilsTest.java @@ -74,7 +74,7 @@ public class ParameterUtilsTest disc = JalviewJabawsTestUtils.getJabawsDiscoverer(); } - @Test(groups = { "Functional" }) + @Test(groups = { "Network" }) public void testWriteParameterSet() throws WrongParameterException { for (Jws2Instance service : disc.getServices()) diff --git a/test/jalview/ws/sifts/SiftsClientTest.java b/test/jalview/ws/sifts/SiftsClientTest.java index 7f8adc9..b92766e 100644 --- a/test/jalview/ws/sifts/SiftsClientTest.java +++ b/test/jalview/ws/sifts/SiftsClientTest.java @@ -514,4 +514,22 @@ groups = { "Network" }, Assert.assertNull(entityP); } + + @Test(groups = { "Network" }) + public void getLeadingIntegerFromString() + { + Assert.assertEquals( + SiftsClient.getLeadingIntegerValue("1234abcd", -1), 1234); + Assert.assertEquals( + SiftsClient.getLeadingIntegerValue("1234", -1), + 1234); + Assert.assertEquals( + SiftsClient.getLeadingIntegerValue("abcd", -1), -1); + Assert.assertEquals( + SiftsClient.getLeadingIntegerValue("abcd1234", -1), -1); + Assert.assertEquals( + SiftsClient.getLeadingIntegerValue("None", -1), -1); + Assert.assertEquals( + SiftsClient.getLeadingIntegerValue("Null", -1), -1); + } }