JAL-2438 unit tests for FeatureColourFinder (transparency tbc!)
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 14 Mar 2017 12:25:35 +0000 (12:25 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 14 Mar 2017 12:25:35 +0000 (12:25 +0000)
test/jalview/renderer/seqfeatures/FeatureColourFinderTest.java [new file with mode: 0644]

diff --git a/test/jalview/renderer/seqfeatures/FeatureColourFinderTest.java b/test/jalview/renderer/seqfeatures/FeatureColourFinderTest.java
new file mode 100644 (file)
index 0000000..6074e85
--- /dev/null
@@ -0,0 +1,378 @@
+package jalview.renderer.seqfeatures;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.api.FeatureColourI;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
+import jalview.gui.FeatureRenderer;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.schemes.FeatureColour;
+
+import java.awt.Color;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Unit tests for feature colour determination, including but not limited to
+ * <ul>
+ * <li>gap position</li>
+ * <li>no features present</li>
+ * <li>features present but show features turned off</li>
+ * <li>features displayed but selected feature turned off</li>
+ * <li>features displayed but feature group turned off</li>
+ * <li>feature displayed but none at the specified position</li>
+ * <li>multiple features at position, with no transparency</li>
+ * <li>multiple features at position, with transparency</li>
+ * <li>score graduated feature colour</li>
+ * <li>contact feature start at the selected position</li>
+ * <li>contact feature end at the selected position</li>
+ * <li>contact feature straddling the selected position (not shown)</li>
+ * </ul>
+ */
+public class FeatureColourFinderTest
+{
+  private AlignViewport av;
+
+  private SequenceI seq;
+
+  private FeatureColourFinder finder;
+
+  private AlignFrame af;
+
+  private FeatureRenderer fr;
+
+  @BeforeClass(alwaysRun = true)
+  public void setUp()
+  {
+    // aligned column 8 is sequence position 6
+    String s = ">s1\nABCDE---FGHIJKLMNOPQRSTUVWXYZ\n";
+    af = new FileLoader().LoadFileWaitTillLoaded(s,
+            DataSourceType.PASTE);
+    av = af.getViewport();
+    seq = av.getAlignment().getSequenceAt(0);
+    fr = af.getFeatureRenderer();
+    finder = new FeatureColourFinder(fr);
+  }
+
+  /**
+   * Clear down any sequence features before each test
+   */
+  @BeforeMethod(alwaysRun = true)
+  public void setUpBeforeTest()
+  {
+    SequenceFeature[] sfs = seq.getSequenceFeatures();
+    if (sfs != null)
+    {
+      for (SequenceFeature sf : sfs)
+      {
+        seq.deleteFeature(sf);
+      }
+    }
+    fr.findAllFeatures(true);
+
+    /*
+     * reset all feature groups to visible
+     */
+    for (String group : fr.getGroups(false))
+    {
+      fr.setGroupVisibility(group, true);
+    }
+  }
+
+  @Test(groups = "Functional")
+  public void testFindFeatureColour_noFeatures()
+  {
+    av.setShowSequenceFeatures(false);
+    Color c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.blue);
+
+    av.setShowSequenceFeatures(true);
+    c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.blue);
+  }
+
+  @Test(groups = "Functional")
+  public void testFindFeatureColour_noFeaturesShown()
+  {
+    seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
+            Float.NaN, "MetalGroup"));
+    fr.featuresAdded();
+    av.setShowSequenceFeatures(false);
+    Color c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.blue);
+  }
+
+  @Test(groups = "Functional")
+  public void testFindFeatureColour_singleFeatureAtPosition()
+  {
+    seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
+            Float.NaN, "MetalGroup"));
+    fr.setColour("Metal", new FeatureColour(Color.red));
+    fr.featuresAdded();
+    av.setShowSequenceFeatures(true);
+    Color c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.red);
+  }
+
+  @Test(groups = "Functional")
+  public void testFindFeatureColour_gapPosition()
+  {
+    seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12, 0f,
+            null));
+    fr.setColour("Metal", new FeatureColour(Color.red));
+    fr.featuresAdded();
+    av.setShowSequenceFeatures(true);
+    Color c = finder.findFeatureColour(null, seq, 6);
+    assertEquals(c, Color.white);
+  }
+
+  @Test(groups = "Functional")
+  public void testFindFeatureColour_multipleFeaturesAtPositionNoTransparency()
+  {
+    /*
+     * featuresAdded -> FeatureRendererModel.updateRenderOrder which adds any
+     * new features 'on top' (but reverses the order of any added features)
+     */
+    seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
+            Float.NaN, "MetalGroup"));
+    FeatureColour red = new FeatureColour(Color.red);
+    fr.setColour("Metal", red);
+    fr.featuresAdded();
+    seq.addSequenceFeature(new SequenceFeature("Domain", "Domain", 4, 15,
+            Float.NaN, "DomainGroup"));
+    FeatureColour green = new FeatureColour(Color.green);
+    fr.setColour("Domain", green);
+    fr.featuresAdded();
+    av.setShowSequenceFeatures(true);
+
+    /*
+     * expect Domain (green) to be rendered above Metal (red)
+     */
+    Color c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.green);
+
+    /*
+     * now promote Metal above Domain
+     * - currently no way other than mimicking reordering of
+     * table in Feature Settings
+     */
+    Object[][] data = new Object[2][];
+    data[0] = new Object[] { "Metal", red, true };
+    data[1] = new Object[] { "Domain", green, true };
+    fr.setFeaturePriority(data);
+    c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.red);
+
+    /*
+     * ..and turn off display of Metal
+     */
+    data[0][2] = false;
+    fr.setFeaturePriority(data);
+    c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.green);
+  }
+
+  @Test(groups = "Functional")
+  public void testFindFeatureColour_singleFeatureNotAtPosition()
+  {
+    seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 8, 12,
+            Float.NaN, "MetalGroup"));
+    fr.setColour("Metal", new FeatureColour(Color.red));
+    fr.featuresAdded();
+    av.setShowSequenceFeatures(true);
+    // column 2 = sequence position 3
+    Color c = finder.findFeatureColour(Color.blue, seq, 2);
+    assertEquals(c, Color.blue);
+  }
+
+  @Test(groups = "Functional")
+  public void testFindFeatureColour_featureTypeNotDisplayed()
+  {
+    seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
+            Float.NaN, "MetalGroup"));
+    FeatureColour red = new FeatureColour(Color.red);
+    fr.setColour("Metal", red);
+    fr.featuresAdded();
+    av.setShowSequenceFeatures(true);
+    Color c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.red);
+
+    /*
+     * turn off display of Metal - is this the easiest way to do it??
+     */
+    Object[][] data = new Object[1][];
+    data[0] = new Object[] { "Metal", red, false };
+    fr.setFeaturePriority(data);
+    c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.blue);
+
+    /*
+     * turn display of Metal back on
+     */
+    data[0] = new Object[] { "Metal", red, true };
+    fr.setFeaturePriority(data);
+    c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.red);
+  }
+
+  @Test(groups = "Functional")
+  public void testFindFeatureColour_featureGroupNotDisplayed()
+  {
+    seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
+            Float.NaN, "MetalGroup"));
+    FeatureColour red = new FeatureColour(Color.red);
+    fr.setColour("Metal", red);
+    fr.featuresAdded();
+    av.setShowSequenceFeatures(true);
+    Color c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.red);
+
+    /*
+     * turn off display of MetalGroup
+     */
+    fr.setGroupVisibility("MetalGroup", false);
+    c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.blue);
+
+    /*
+     * turn display of MetalGroup back on
+     */
+    fr.setGroupVisibility("MetalGroup", true);
+    c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.red);
+  }
+
+  @Test(groups = "Functional")
+  public void testFindFeatureColour_contactFeature()
+  {
+    /*
+     * currently contact feature == type "Disulphide Bond" or "Disulfide Bond" !!
+     */
+    seq.addSequenceFeature(new SequenceFeature("Disulphide Bond",
+            "Contact", 2, 12, Float.NaN, "Disulphide"));
+    fr.setColour("Disulphide Bond", new FeatureColour(Color.red));
+    fr.featuresAdded();
+    av.setShowSequenceFeatures(true);
+
+    /*
+     * Contact positions are residues 2 and 12
+     * which are columns 1 and 14
+     * positions in between don't count for a contact feature!
+     */
+    Color c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.blue);
+    c = finder.findFeatureColour(Color.blue, seq, 8);
+    assertEquals(c, Color.blue);
+    c = finder.findFeatureColour(Color.blue, seq, 1);
+    assertEquals(c, Color.red);
+    c = finder.findFeatureColour(Color.blue, seq, 14);
+    assertEquals(c, Color.red);
+  }
+
+  @Test(groups = "Functional")
+  public void testFindFeatureColour_graduatedFeatureColour()
+  {
+    seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 2,
+            2, 0f, "KdGroup"));
+    seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 4,
+            4, 5f, "KdGroup"));
+    seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 7,
+            7, 10f, "KdGroup"));
+
+    /*
+     * graduated colour from 0 to 10
+     */
+    Color min = new Color(100, 50, 150);
+    Color max = new Color(200, 0, 100);
+    FeatureColourI fc = new FeatureColour(min, max, 0, 10);
+    fr.setColour("kd", fc);
+    fr.featuresAdded();
+    av.setShowSequenceFeatures(true);
+
+    /*
+     * position 2, column 1, score 0 - minimum colour in range
+     */
+    Color c = finder.findFeatureColour(Color.blue, seq, 1);
+    assertEquals(c, min);
+
+    /*
+     * position 7, column 9, score 10 - maximum colour in range
+     */
+    c = finder.findFeatureColour(Color.blue, seq, 9);
+    assertEquals(c, max);
+
+    /*
+     * position 4, column 3, score 5 - half way from min to max
+     */
+    c = finder.findFeatureColour(Color.blue, seq, 3);
+    assertEquals(c, new Color(150, 25, 125));
+  }
+
+  @Test(groups = "Functional")
+  public void testFindFeatureColour_transparencySingleFeature()
+  {
+    seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
+            Float.NaN, "MetalGroup"));
+    FeatureColour red = new FeatureColour(Color.red);
+    fr.setColour("Metal", red);
+    fr.featuresAdded();
+    av.setShowSequenceFeatures(true);
+  
+    /*
+     * the FeatureSettings transparency slider has range 0-70 which
+     * corresponds to a transparency value of 1 - 0.3
+     */
+    fr.setTransparency(0.5f);
+    Color c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, new Color(85, 170, 0));
+  }
+
+  @Test(groups = "Functional")
+  public void testFindFeatureColour_transparencyTwoFeatures()
+  {
+    seq.addSequenceFeature(new SequenceFeature("Metal", "Metal", 2, 12,
+            Float.NaN, "MetalGroup"));
+    FeatureColour red = new FeatureColour(Color.red);
+    fr.setColour("Metal", red);
+    fr.featuresAdded();
+    seq.addSequenceFeature(new SequenceFeature("Domain", "Domain", 4, 15,
+            Float.NaN, "DomainGroup"));
+    FeatureColour green = new FeatureColour(Color.green);
+    fr.setColour("Domain", green);
+    fr.featuresAdded();
+    av.setShowSequenceFeatures(true);
+  
+    /*
+     * Domain (green(0, 255, 0)) rendered above Metal (red(255, 0, 0))
+     */
+    fr.setTransparency(0.5f);
+    Color c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, new Color(85, 170, 0));
+  
+    /*
+     * now promote Metal above Domain
+     * - currently no way other than mimicking reordering of
+     * table in Feature Settings
+     */
+    Object[][] data = new Object[2][];
+    data[0] = new Object[] { "Metal", red, true };
+    data[1] = new Object[] { "Domain", green, true };
+    fr.setFeaturePriority(data);
+    c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, new Color(153, 102, 0));
+  
+    /*
+     * ..and turn off display of Metal
+     */
+    data[0][2] = false;
+    fr.setFeaturePriority(data);
+    c = finder.findFeatureColour(Color.blue, seq, 10);
+    assertEquals(c, Color.green);
+  }
+}