import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
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.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;
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));
* 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"));
/*
/*
* 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);
features = fr.findFeaturesAtColumn(seq, 5);
assertEquals(features.size(), 1);
assertTrue(features.contains(sf8));
-
+
/*
* give "Type3" features a graduated colour scheme
* - first with no threshold
assertFalse(features.contains(sf2) && features.contains(sf3));
assertTrue(features.contains(sf5));
}
+
+ @Test(groups = "Functional")
+ public void testGetColour()
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(">s1\nABCD\n",
+ DataSourceType.PASTE);
+ AlignViewportI av = af.getViewport();
+ FeatureRenderer fr = new FeatureRenderer(av);
+
+ /*
+ * simple colour, feature type and group displayed
+ */
+ FeatureColourI fc = new FeatureColour(Color.red);
+ fr.getFeatureColours().put("Cath", fc);
+ SequenceFeature sf1 = new SequenceFeature("Cath", "", 6, 8, Float.NaN,
+ "group1");
+ assertEquals(fr.getColour(sf1), Color.red);
+
+ /*
+ * hide feature type, then unhide
+ * - feature type visibility should not affect the result
+ */
+ FeatureSettingsBean[] data = new FeatureSettingsBean[1];
+ data[0] = new FeatureSettingsBean("Cath", fc, null, false);
+ fr.setFeaturePriority(data);
+ assertEquals(fr.getColour(sf1), Color.red);
+ data[0] = new FeatureSettingsBean("Cath", fc, null, true);
+ fr.setFeaturePriority(data);
+ assertEquals(fr.getColour(sf1), Color.red);
+
+ /*
+ * hide feature group, then unhide
+ */
+ fr.setGroupVisibility("group1", false);
+ assertNull(fr.getColour(sf1));
+ fr.setGroupVisibility("group1", true);
+ assertEquals(fr.getColour(sf1), Color.red);
+
+ /*
+ * graduated colour by score, no threshold, no score
+ *
+ */
+ FeatureColourI gc = new FeatureColour(Color.yellow, Color.red,
+ Color.green, 1f, 11f);
+ fr.getFeatureColours().put("Cath", gc);
+ assertEquals(fr.getColour(sf1), Color.green);
+
+ /*
+ * graduated colour by score, no threshold, with score value
+ */
+ SequenceFeature sf2 = new SequenceFeature("Cath", "", 6, 8, 6f,
+ "group1");
+ // score 6 is half way from yellow(255, 255, 0) to red(255, 0, 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), 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);
+ 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));
+
+ /*
+ * feature score is below threshold - no colour
+ */
+ gc.setAboveThreshold(true);
+ gc.setThreshold(7f);
+ assertNull(fr.getColour(sf2));
+
+ /*
+ * feature score is above threshold - no colour
+ */
+ gc.setBelowThreshold(true);
+ gc.setThreshold(3f);
+ assertNull(fr.getColour(sf2));
+
+ /*
+ * colour by feature attribute value
+ * first with no value held
+ */
+ gc = new FeatureColour(Color.yellow, Color.red, Color.green, 1f, 11f);
+ fr.getFeatureColours().put("Cath", gc);
+ gc.setAttributeName("AF");
+ assertEquals(fr.getColour(sf2), Color.green);
+
+ // with non-numeric attribute value
+ sf2.setValue("AF", "Five");
+ assertEquals(fr.getColour(sf2), Color.green);
+
+ // with numeric attribute value
+ sf2.setValue("AF", "6");
+ assertEquals(fr.getColour(sf2), expected);
+
+ // with numeric value outwith threshold
+ gc.setAboveThreshold(true);
+ gc.setThreshold(10f);
+ assertNull(fr.getColour(sf2));
+
+ // with filter on AF < 4
+ gc.setAboveThreshold(false);
+ 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 FeatureMatcherSet();
+ filter.and(FeatureMatcher.byAttribute(Condition.Contains, "missense",
+ "Consequence"));
+ fr.setFeatureFilter("Cath", filter);
+ // if feature has no Consequence attribute, no colour
+ assertNull(fr.getColour(sf2));
+ // if attribute does not match filter, no colour
+ sf2.setValue("Consequence", "Synonymous");
+ assertNull(fr.getColour(sf2));
+ // attribute matches filter
+ sf2.setValue("Consequence", "Missense variant");
+ 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<String, String> 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);
+ }
}