Merge remote-tracking branch 'origin/develop' into
authorkiramt <k.mourao@dundee.ac.uk>
Fri, 5 May 2017 09:35:48 +0000 (10:35 +0100)
committerkiramt <k.mourao@dundee.ac.uk>
Fri, 5 May 2017 09:35:48 +0000 (10:35 +0100)
features/JAL-2388hiddencolumnschanges

Conflicts:
src/jalview/gui/AnnotationColumnChooser.java
src/jalview/io/AnnotationFile.java

33 files changed:
examples/appletParameters.html
examples/testdata/example_annot_file.jva
help/html/features/preferences.html
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/jalview/analysis/AAFrequency.java
src/jalview/appletgui/AlignViewport.java
src/jalview/appletgui/AnnotationColumnChooser.java
src/jalview/appletgui/AnnotationRowFilter.java
src/jalview/datamodel/Alignment.java
src/jalview/datamodel/AlignmentView.java
src/jalview/datamodel/AnnotatedCollectionI.java
src/jalview/datamodel/SequenceGroup.java
src/jalview/ext/ensembl/EnsemblRestClient.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/AnnotationColumnChooser.java
src/jalview/gui/AnnotationRowFilter.java
src/jalview/gui/Preferences.java
src/jalview/io/AnnotationFile.java
src/jalview/io/JSONFile.java
src/jalview/jbgui/GPreferences.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/ws/sifts/SiftsClient.java
test/jalview/datamodel/AlignmentTest.java
test/jalview/datamodel/AlignmentViewTest.java
test/jalview/gui/AlignViewportTest.java
test/jalview/gui/StructureChooserTest.java
test/jalview/io/AnnotationFileIOTest.java
test/jalview/io/JSONFileTest.java
test/jalview/io/testProps.jvprops
test/jalview/ws/dbsources/RemoteFormatTest.java [new file with mode: 0644]
test/jalview/ws/jws2/ParameterUtilsTest.java
test/jalview/ws/sifts/SiftsClientTest.java

index 7959c3a..04cc235 100644 (file)
@@ -159,6 +159,11 @@ the applet can be interacted with <em>via</em> its
             <td>Default is true.</td>
           </tr>
           <tr> 
+            <td>showOccupancy</td>
+            <td>true <em>or</em> false</td>
+            <td>Default is true.</td>
+          </tr>
+          <tr> 
             <td>sortBy</td>
             <td> Id <em>, </em> Pairwise Identity<em>, or</em> Length</td>
             <td> Sorts the alignment on startup</td>
index 794f42b..1779247 100644 (file)
@@ -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
index da045ba..6e8d3e4 100755 (executable)
   <p>
     <em>Show Annotations</em> - 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 <em>Conservation</em>, <em>Quality</em> and <em>Consensus</em>
-    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 <em>Conservation</em>, <em>Quality</em>, 
+    <em>Occupancy</em> and <em>Consensus</em> for the alignment may 
+    be shown or hidden by default using the checkboxes adjacent and
+    below.
   </p>
   <p>
     <em>Show group: Conservation and Consensus</em> controls the display
index 4ebca62..922f482 100644 (file)
@@ -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_<schemeName> 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
index bdd61fe..e6e1872 100644 (file)
@@ -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_<schemeName> 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!
index ee16f94..b806355 100755 (executable)
  */
 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));
     }
   }
 
index d11ed48..61621ae 100644 (file)
@@ -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()));
 
index 7efb490..2acb568 100644 (file)
@@ -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);
     }
index 8d67d71..315ce3b 100644 (file)
@@ -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
index cff3890..fcb6109 100755 (executable)
@@ -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<AlignmentAnnotation> findAnnotations(SequenceI seq,
           String calcId, String label)
@@ -1655,9 +1651,11 @@ public class Alignment implements AlignmentI
     ArrayList<AlignmentAnnotation> aa = new ArrayList<AlignmentAnnotation>();
     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);
       }
index a61d0d1..5058dcf 100644 (file)
@@ -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 };
     }
   }
 
index 3f6c515..2963fd5 100644 (file)
@@ -40,6 +40,17 @@ public interface AnnotatedCollectionI extends SequenceCollectionI
    */
   Iterable<AlignmentAnnotation> 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<AlignmentAnnotation> findAnnotations(SequenceI seq,
           String calcId, String label);
 
index 1246d23..76ad093 100755 (executable)
@@ -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<AlignmentAnnotation> findAnnotations(SequenceI seq,
           String calcId, String label)
@@ -1302,9 +1296,11 @@ public class SequenceGroup implements AnnotatedCollectionI
     ArrayList<AlignmentAnnotation> aa = new ArrayList<AlignmentAnnotation>();
     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);
       }
index ab3b197..5960f81 100644 (file)
@@ -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)
index d87d947..73f81bc 100644 (file)
@@ -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
index fa63e0d..0fe6462 100644 (file)
@@ -110,20 +110,23 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
 
     setAnnotations(new JComboBox<String>(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);
index c2bf41b..a3ce528 100644 (file)
@@ -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);
index cf80a6d..cccdd2e 100755 (executable)
@@ -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()
index 31aeffa..e685627 100755 (executable)
@@ -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<SequenceGroup> list)
+  protected void printGroups(List<SequenceGroup> 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)
         {
index d6be51c..93a0167 100644 (file)
@@ -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();
 
index dda06b4..1ad95dd 100755 (executable)
@@ -101,6 +101,8 @@ public class GPreferences extends JPanel
 
   protected JComboBox<String> fontNameCB = new JComboBox<String>();
 
+  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);
index 9c8c233..6a38f21 100644 (file)
@@ -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<SequenceI, Color> sequenceColours = new HashMap<SequenceI, Color>();
 
   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;
index c69581f..fe3a25b 100644 (file)
@@ -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.
index c5d09c1..660a69c 100644 (file)
@@ -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<AlignmentAnnotation> anns = al.findAnnotations(null,
+            "CalcIdForD.melanogaster.2", null);
+    Iterator<AlignmentAnnotation> 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()
   {
index 594d6e6..b201c7e 100644 (file)
@@ -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 });
+  }
 }
index 06df70a..e6c16b7 100644 (file)
@@ -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.");
+
+  }
 }
index b7eef0f..c04353f 100644 (file)
@@ -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 };
index c3a1801..105f6e4 100644 (file)
@@ -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(
index 6ccbd5d..3b418ec 100644 (file)
@@ -130,13 +130,14 @@ public class JSONFileTest
       expectedSeqs.put(seq.getName(), seq);
     }
 
-    // create and add sequence groups
-    ArrayList<SequenceI> grpSeqs = new ArrayList<SequenceI>();
+    // create and add a sequence group
+    List<SequenceI> grpSeqs = new ArrayList<SequenceI>();
     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<SequenceI>(),
+            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);
+  }
 }
index 95da22e..8ede59c 100644 (file)
@@ -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 (file)
index 0000000..90d4472
--- /dev/null
@@ -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.
+ * <p>
+ * 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<DbSourceProxy> 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<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
+    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");
+  }
+}
index e859cb0..c0aa2ee 100644 (file)
@@ -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())
index 7f8adc9..b92766e 100644 (file)
@@ -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);
+  }
 }