X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Frenderer%2Fseqfeatures%2FFeatureRendererTest.java;h=723f3b8c9dcf3cc7e8404cc1d0bf0908bfda2801;hb=3c8a25936a2d805e7e3d7ab82f83b13135406d18;hp=821c3b778c1e2fb78ed7a35367a79254c90bd469;hpb=3560e7483e384409a8760a81dac9a424a66f7a17;p=jalview.git
diff --git a/test/jalview/renderer/seqfeatures/FeatureRendererTest.java b/test/jalview/renderer/seqfeatures/FeatureRendererTest.java
index 821c3b7..723f3b8 100644
--- a/test/jalview/renderer/seqfeatures/FeatureRendererTest.java
+++ b/test/jalview/renderer/seqfeatures/FeatureRendererTest.java
@@ -1,3 +1,23 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see .
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.renderer.seqfeatures;
import static org.testng.Assert.assertEquals;
@@ -9,18 +29,20 @@ import jalview.api.AlignViewportI;
import jalview.api.FeatureColourI;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.FeatureMatcher;
+import jalview.datamodel.features.FeatureMatcherSet;
+import jalview.datamodel.features.FeatureMatcherSetI;
import jalview.gui.AlignFrame;
import jalview.io.DataSourceType;
import jalview.io.FileLoader;
import jalview.schemes.FeatureColour;
import jalview.util.matcher.Condition;
-import jalview.util.matcher.KeyedMatcher;
-import jalview.util.matcher.KeyedMatcherSet;
-import jalview.util.matcher.KeyedMatcherSetI;
+import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -66,9 +88,8 @@ public class FeatureRendererTest
seqs.get(2).addSequenceFeature(
new SequenceFeature("Pfam", "Desc", 14, 22, 2f, "RfamGroup"));
// bug in findAllFeatures - group not checked for a known feature type
- seqs.get(2).addSequenceFeature(
- new SequenceFeature("Rfam", "Desc", 5, 9, Float.NaN,
- "RfamGroup"));
+ seqs.get(2).addSequenceFeature(new SequenceFeature("Rfam", "Desc", 5, 9,
+ Float.NaN, "RfamGroup"));
// existing feature type with null group
seqs.get(3).addSequenceFeature(
new SequenceFeature("Rfam", "Desc", 5, 9, Float.NaN, null));
@@ -121,13 +142,14 @@ public class FeatureRendererTest
* change render order (todo: an easier way)
* nb here last comes first in the data array
*/
- Object[][] data = new Object[3][];
+ FeatureSettingsBean[] data = new FeatureSettingsBean[3];
FeatureColourI colour = new FeatureColour(Color.RED);
- data[0] = new Object[] { "Rfam", colour, true };
- data[1] = new Object[] { "Pfam", colour, false };
- data[2] = new Object[] { "Scop", colour, false };
+ data[0] = new FeatureSettingsBean("Rfam", colour, null, true);
+ data[1] = new FeatureSettingsBean("Pfam", colour, null, false);
+ data[2] = new FeatureSettingsBean("Scop", colour, null, false);
fr.setFeaturePriority(data);
- assertEquals(fr.getRenderOrder(), Arrays.asList("Scop", "Pfam", "Rfam"));
+ assertEquals(fr.getRenderOrder(),
+ Arrays.asList("Scop", "Pfam", "Rfam"));
assertEquals(fr.getDisplayedFeatureTypes(), Arrays.asList("Rfam"));
/*
@@ -222,12 +244,13 @@ public class FeatureRendererTest
/*
* make "Type2" not displayed
*/
- Object[][] data = new Object[4][];
FeatureColourI colour = new FeatureColour(Color.RED);
- data[0] = new Object[] { "Type1", colour, true };
- data[1] = new Object[] { "Type2", colour, false };
- data[2] = new Object[] { "Type3", colour, true };
- data[3] = new Object[] { "Disulphide Bond", colour, true };
+ FeatureSettingsBean[] data = new FeatureSettingsBean[4];
+ data[0] = new FeatureSettingsBean("Type1", colour, null, true);
+ data[1] = new FeatureSettingsBean("Type2", colour, null, false);
+ data[2] = new FeatureSettingsBean("Type3", colour, null, true);
+ data[3] = new FeatureSettingsBean("Disulphide Bond", colour, null,
+ true);
fr.setFeaturePriority(data);
features = fr.findFeaturesAtColumn(seq, 15);
@@ -257,13 +280,13 @@ public class FeatureRendererTest
features = fr.findFeaturesAtColumn(seq, 5);
assertEquals(features.size(), 1);
assertTrue(features.contains(sf8));
-
+
/*
* give "Type3" features a graduated colour scheme
* - first with no threshold
*/
- FeatureColourI gc = new FeatureColour(Color.yellow, Color.red, null, 0f,
- 10f);
+ FeatureColourI gc = new FeatureColour(Color.green, Color.yellow,
+ Color.red, null, 0f, 10f);
fr.getFeatureColours().put("Type3", gc);
features = fr.findFeaturesAtColumn(seq, 8);
assertTrue(features.contains(sf4));
@@ -305,18 +328,18 @@ public class FeatureRendererTest
SequenceI seq = av.getAlignment().getSequenceAt(0);
SequenceFeature sf1 = new SequenceFeature("Cath", "", 6, 8, Float.NaN,
"group1");
- seq.addSequenceFeature(sf1);
SequenceFeature sf2 = new SequenceFeature("Cath", "", 5, 11, 2f,
"group2");
- seq.addSequenceFeature(sf2);
SequenceFeature sf3 = new SequenceFeature("Cath", "", 5, 11, 3f,
"group3");
- seq.addSequenceFeature(sf3);
SequenceFeature sf4 = new SequenceFeature("Cath", "", 6, 8, 4f,
"group4");
- seq.addSequenceFeature(sf4);
SequenceFeature sf5 = new SequenceFeature("Cath", "", 6, 9, 5f,
"group4");
+ seq.addSequenceFeature(sf1);
+ seq.addSequenceFeature(sf2);
+ seq.addSequenceFeature(sf3);
+ seq.addSequenceFeature(sf4);
seq.addSequenceFeature(sf5);
fr.findAllFeatures(true);
@@ -342,18 +365,26 @@ public class FeatureRendererTest
assertTrue(features.contains(sf5));
/*
- * hide groups 2 and 3 makes no difference to this method
+ * features in hidden groups are removed
*/
fr.setGroupVisibility("group2", false);
fr.setGroupVisibility("group3", false);
features = seq.getSequenceFeatures();
fr.filterFeaturesForDisplay(features);
- assertEquals(features.size(), 3);
+ assertEquals(features.size(), 2);
assertTrue(features.contains(sf1) || features.contains(sf4));
assertFalse(features.contains(sf1) && features.contains(sf4));
- assertTrue(features.contains(sf2) || features.contains(sf3));
- assertFalse(features.contains(sf2) && features.contains(sf3));
+ assertFalse(features.contains(sf2));
+ assertFalse(features.contains(sf3));
assertTrue(features.contains(sf5));
+
+ /*
+ * no filtering if transparency is applied
+ */
+ fr.setTransparency(0.5f);
+ features = seq.getSequenceFeatures();
+ fr.filterFeaturesForDisplay(features);
+ assertEquals(features.size(), 5);
}
@Test(groups = "Functional")
@@ -375,12 +406,13 @@ public class FeatureRendererTest
/*
* hide feature type, then unhide
+ * - feature type visibility should not affect the result
*/
- Object[][] data = new Object[1][];
- data[0] = new Object[] { "Cath", fc, false };
+ FeatureSettingsBean[] data = new FeatureSettingsBean[1];
+ data[0] = new FeatureSettingsBean("Cath", fc, null, false);
fr.setFeaturePriority(data);
- assertNull(fr.getColour(sf1));
- data[0] = new Object[] { "Cath", fc, true };
+ assertEquals(fr.getColour(sf1), Color.red);
+ data[0] = new FeatureSettingsBean("Cath", fc, null, true);
fr.setFeaturePriority(data);
assertEquals(fr.getColour(sf1), Color.red);
@@ -396,8 +428,8 @@ public class FeatureRendererTest
* graduated colour by score, no threshold, no score
*
*/
- FeatureColourI gc = new FeatureColour(Color.yellow, Color.red,
- Color.green, 1f, 11f);
+ FeatureColourI gc = new FeatureColour(Color.red, Color.yellow,
+ Color.red, Color.green, 1f, 11f);
fr.getFeatureColours().put("Cath", gc);
assertEquals(fr.getColour(sf1), Color.green);
@@ -407,20 +439,22 @@ public class FeatureRendererTest
SequenceFeature sf2 = new SequenceFeature("Cath", "", 6, 8, 6f,
"group1");
// score 6 is half way from yellow(255, 255, 0) to red(255, 0, 0)
- assertEquals(fr.getColour(sf2), new Color(255, 128, 0));
-
+ Color expected = new Color(255, 128, 0);
+ assertEquals(fr.getColour(sf2), expected);
+
/*
* above threshold, score is above threshold - no change
*/
gc.setAboveThreshold(true);
gc.setThreshold(5f);
- assertEquals(fr.getColour(sf2), new Color(255, 128, 0));
+ assertEquals(fr.getColour(sf2), expected);
/*
* threshold is min-max; now score 6 is 1/6 of the way from 5 to 11
* or from yellow(255, 255, 0) to red(255, 0, 0)
*/
- gc = new FeatureColour(Color.yellow, Color.red, Color.green, 5f, 11f);
+ gc = new FeatureColour(Color.red, Color.yellow, Color.red, Color.green,
+ 5f, 11f);
fr.getFeatureColours().put("Cath", gc);
gc.setAutoScaled(false); // this does little other than save a checkbox setting!
assertEquals(fr.getColour(sf2), new Color(255, 213, 0));
@@ -443,7 +477,8 @@ public class FeatureRendererTest
* colour by feature attribute value
* first with no value held
*/
- gc = new FeatureColour(Color.yellow, Color.red, Color.green, 1f, 11f);
+ gc = new FeatureColour(Color.red, Color.yellow, Color.red, Color.green,
+ 1f, 11f);
fr.getFeatureColours().put("Cath", gc);
gc.setAttributeName("AF");
assertEquals(fr.getColour(sf2), Color.green);
@@ -454,7 +489,7 @@ public class FeatureRendererTest
// with numeric attribute value
sf2.setValue("AF", "6");
- assertEquals(fr.getColour(sf2), new Color(255, 128, 0));
+ assertEquals(fr.getColour(sf2), expected);
// with numeric value outwith threshold
gc.setAboveThreshold(true);
@@ -463,15 +498,15 @@ public class FeatureRendererTest
// with filter on AF < 4
gc.setAboveThreshold(false);
- assertEquals(fr.getColour(sf2), new Color(255, 128, 0));
- KeyedMatcherSetI filter = new KeyedMatcherSet();
- filter.and(new KeyedMatcher(Condition.LT, 4f, "AF"));
+ assertEquals(fr.getColour(sf2), expected);
+ FeatureMatcherSetI filter = new FeatureMatcherSet();
+ filter.and(FeatureMatcher.byAttribute(Condition.LT, "4.0", "AF"));
fr.setFeatureFilter("Cath", filter);
assertNull(fr.getColour(sf2));
// with filter on 'Consequence contains missense'
- filter = new KeyedMatcherSet();
- filter.and(new KeyedMatcher(Condition.Contains, "missense",
+ filter = new FeatureMatcherSet();
+ filter.and(FeatureMatcher.byAttribute(Condition.Contains, "missense",
"Consequence"));
fr.setFeatureFilter("Cath", filter);
// if feature has no Consequence attribute, no colour
@@ -481,6 +516,92 @@ public class FeatureRendererTest
assertNull(fr.getColour(sf2));
// attribute matches filter
sf2.setValue("Consequence", "Missense variant");
- assertEquals(fr.getColour(sf2), new Color(255, 128, 0));
+ assertEquals(fr.getColour(sf2), expected);
+
+ // with filter on CSQ:Feature contains "ENST01234"
+ filter = new FeatureMatcherSet();
+ filter.and(FeatureMatcher.byAttribute(Condition.Matches, "ENST01234",
+ "CSQ", "Feature"));
+ fr.setFeatureFilter("Cath", filter);
+ // if feature has no CSQ data, no colour
+ assertNull(fr.getColour(sf2));
+ // if CSQ data does not include Feature, no colour
+ Map csqData = new HashMap<>();
+ csqData.put("BIOTYPE", "Transcript");
+ sf2.setValue("CSQ", csqData);
+ assertNull(fr.getColour(sf2));
+ // if attribute does not match filter, no colour
+ csqData.put("Feature", "ENST9876");
+ assertNull(fr.getColour(sf2));
+ // attribute matches filter
+ csqData.put("Feature", "ENST01234");
+ assertEquals(fr.getColour(sf2), expected);
+ }
+
+ @Test(groups = "Functional")
+ public void testIsVisible()
+ {
+ String seqData = ">s1\nMLQGIFPRS\n";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqData,
+ DataSourceType.PASTE);
+ AlignViewportI av = af.getViewport();
+ FeatureRenderer fr = new FeatureRenderer(av);
+ SequenceI seq = av.getAlignment().getSequenceAt(0);
+ SequenceFeature sf = new SequenceFeature("METAL", "Desc", 10, 10, 1f,
+ "Group");
+ sf.setValue("AC", "11");
+ sf.setValue("CLIN_SIG", "Likely Pathogenic");
+ seq.addSequenceFeature(sf);
+
+ assertFalse(fr.isVisible(null));
+
+ /*
+ * initial state FeatureRenderer hasn't 'found' feature
+ * and so its feature type has not yet been set visible
+ */
+ assertFalse(fr.getDisplayedFeatureCols().containsKey("METAL"));
+ assertFalse(fr.isVisible(sf));
+
+ fr.findAllFeatures(true);
+ assertTrue(fr.isVisible(sf));
+
+ /*
+ * feature group not visible
+ */
+ fr.setGroupVisibility("Group", false);
+ assertFalse(fr.isVisible(sf));
+ fr.setGroupVisibility("Group", true);
+ assertTrue(fr.isVisible(sf));
+
+ /*
+ * feature score outwith colour threshold (score > 2)
+ */
+ FeatureColourI fc = new FeatureColour(null, Color.white, Color.black,
+ Color.white, 0, 10);
+ fc.setAboveThreshold(true);
+ fc.setThreshold(2f);
+ fr.setColour("METAL", fc);
+ assertFalse(fr.isVisible(sf)); // score 1 is not above threshold 2
+ fc.setBelowThreshold(true);
+ assertTrue(fr.isVisible(sf)); // score 1 is below threshold 2
+
+ /*
+ * colour with threshold on attribute AC (value is 11)
+ */
+ fc.setAttributeName("AC");
+ assertFalse(fr.isVisible(sf)); // value 11 is not below threshold 2
+ fc.setAboveThreshold(true);
+ assertTrue(fr.isVisible(sf)); // value 11 is above threshold 2
+
+ fc.setAttributeName("AF"); // attribute AF is absent in sf
+ assertTrue(fr.isVisible(sf)); // feature is not excluded by threshold
+
+ FeatureMatcherSetI filter = new FeatureMatcherSet();
+ filter.and(FeatureMatcher.byAttribute(Condition.Contains, "pathogenic",
+ "CLIN_SIG"));
+ fr.setFeatureFilter("METAL", filter);
+ assertTrue(fr.isVisible(sf)); // feature matches filter
+ filter.and(FeatureMatcher.byScore(Condition.LE, "0.4"));
+ assertFalse(fr.isVisible(sf)); // feature doesn't match filter
}
}