{
String type = SequenceOntologyI.SEQUENCE_VARIANT;
+ /*
+ * could we associate Consequence data with this allele and feature (transcript)?
+ * if so, prefer the consequence term from that data
+ */
if (csqAlleleFieldIndex == -1) // && snpEffAlleleFieldIndex == -1
{
/*
return type;
}
- /*
- * can we associate Consequence data with this allele and feature (transcript)?
- * if so, prefer the consequence term from that data
- */
if (consequence != null)
{
String[] csqFields = consequence.split(PIPE_REGEX);
}
/*
+ * filter out fields we don't want to capture
+ */
+ if (!vcfFieldsOfInterest.contains(key))
+ {
+ continue;
+ }
+
+ /*
* we extract values for other data which are allele-specific;
* these may be per alternate allele (INFO[key].Number = 'A')
* or per allele including reference (INFO[key].Number = 'R')
String myConsequence)
{
Object value = variant.getAttribute(CSQ_FIELD);
- // TODO if CSQ not present, try ANN (for SnpEff consequence data)?
if (value == null || !(value instanceof List<?>))
{
+++ /dev/null
-package jalview.util.matcher;
-
-import java.util.function.Function;
-
-/**
- * An immutable class that models one or more match conditions, each of which is
- * applied to the value obtained by lookup given the match key.
- * <p>
- * For example, the value provider could be a SequenceFeature's attributes map,
- * and the conditions might be
- * <ul>
- * <li>CSQ contains "pathological"</li>
- * <li>AND</li>
- * <li>AF <= 1.0e-5</li>
- * </ul>
- *
- * @author gmcarstairs
- *
- */
-public class KeyedMatcher implements KeyedMatcherI
-{
- private static final String COLON = ":";
-
- final private String[] key;
-
- final private MatcherI matcher;
-
- /**
- * Constructor given a key, a test condition and a match pattern
- *
- * @param cond
- * @param pattern
- * @param theKey
- */
- public KeyedMatcher(Condition cond, String pattern, String... theKey)
- {
- key = theKey;
- matcher = new Matcher(cond, pattern);
- }
-
- /**
- * Constructor given a key, a test condition and a numerical value to compare
- * to. Note that if a non-numerical condition is specified, the float will be
- * converted to a string.
- *
- * @param cond
- * @param value
- * @param theKey
- */
- public KeyedMatcher(Condition cond, float value, String... theKey)
- {
- key = theKey;
- matcher = new Matcher(cond, value);
- }
-
- @Override
- public boolean matches(Function<String[], String> valueProvider)
- {
- String value = valueProvider.apply(key);
- return matcher.matches(value);
- }
-
- @Override
- public String[] getKey()
- {
- return key;
- }
-
- @Override
- public MatcherI getMatcher()
- {
- return matcher;
- }
-
- /**
- * Answers a string description of this matcher, suitable for display, debugging
- * or logging. The format may change in future.
- */
- @Override
- public String toString()
- {
- StringBuilder sb = new StringBuilder();
- sb.append(String.join(COLON, key)).append(" ")
- .append(matcher.getCondition().toString());
- Condition condition = matcher.getCondition();
- if (condition.isNumeric())
- {
- sb.append(" ").append(matcher.getPattern());
- }
- else if (condition != Condition.Present
- && condition != Condition.NotPresent)
- {
- sb.append(" '").append(matcher.getPattern()).append("'");
- }
-
- return sb.toString();
- }
-}
+++ /dev/null
-package jalview.util.matcher;
-
-import java.util.function.Function;
-
-/**
- * An interface for an object that can apply one or more match conditions, given
- * a key-value provider. The match conditions are stored against key values, and
- * applied to the value obtained by a key-value lookup.
- *
- * @author gmcarstairs
- */
-public interface KeyedMatcherI
-{
- /**
- * Answers true if the value provided for this matcher's key passes this
- * matcher's match condition
- *
- * @param valueProvider
- * @return
- */
- boolean matches(Function<String[], String> valueProvider);
-
- /**
- * Answers the value key this matcher operates on
- *
- * @return
- */
- String[] getKey();
-
- /**
- * Answers the match condition that is applied
- *
- * @return
- */
- MatcherI getMatcher();
-}
+++ /dev/null
-package jalview.util.matcher;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Function;
-
-public class KeyedMatcherSet implements KeyedMatcherSetI
-{
- List<KeyedMatcherI> matchConditions;
-
- boolean andConditions;
-
- /**
- * Constructor
- */
- public KeyedMatcherSet()
- {
- matchConditions = new ArrayList<>();
- }
-
- @Override
- public boolean matches(Function<String[], String> valueProvider)
- {
- /*
- * no conditions matches anything
- */
- if (matchConditions.isEmpty())
- {
- return true;
- }
-
- /*
- * AND until failure
- */
- if (andConditions)
- {
- for (KeyedMatcherI m : matchConditions)
- {
- if (!m.matches(valueProvider))
- {
- return false;
- }
- }
- return true;
- }
-
- /*
- * OR until match
- */
- for (KeyedMatcherI m : matchConditions)
- {
- if (m.matches(valueProvider))
- {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public KeyedMatcherSetI and(KeyedMatcherI m)
- {
- if (!andConditions && matchConditions.size() > 1)
- {
- throw new IllegalStateException("Can't add an AND to OR conditions");
- }
- matchConditions.add(m);
- andConditions = true;
-
- return this;
- }
-
- @Override
- public KeyedMatcherSetI or(KeyedMatcherI m)
- {
- if (andConditions && matchConditions.size() > 1)
- {
- throw new IllegalStateException("Can't add an OR to AND conditions");
- }
- matchConditions.add(m);
- andConditions = false;
-
- return this;
- }
-
- @Override
- public boolean isAnded()
- {
- return andConditions;
- }
-
- @Override
- public Iterable<KeyedMatcherI> getMatchers()
- {
- return matchConditions;
- }
-
- @Override
- public String toString()
- {
- StringBuilder sb = new StringBuilder();
- boolean first = true;
- for (KeyedMatcherI matcher : matchConditions)
- {
- if (!first)
- {
- sb.append(andConditions ? " AND " : " OR ");
- }
- first = false;
- sb.append("(").append(matcher.toString()).append(")");
- }
- return sb.toString();
- }
-
- @Override
- public boolean isEmpty()
- {
- return matchConditions == null || matchConditions.isEmpty();
- }
-
-}
+++ /dev/null
-package jalview.util.matcher;
-
-import java.util.function.Function;
-
-/**
- * An interface to describe a set of one or more key-value match conditions,
- * where all conditions are combined with either AND or OR
- *
- * @author gmcarstairs
- *
- */
-public interface KeyedMatcherSetI
-{
- /**
- * Answers true if the value provided for this matcher's key passes this
- * matcher's match condition
- *
- * @param valueProvider
- * @return
- */
- boolean matches(Function<String[], String> valueProvider);
-
- /**
- * Answers a new object that matches the logical AND of this and m
- *
- * @param m
- * @return
- * @throws IllegalStateException
- * if an attempt is made to AND to existing OR-ed conditions
- */
- KeyedMatcherSetI and(KeyedMatcherI m);
-
- /**
- * Answers true if any second condition is AND-ed with this one, false if it
- * is OR-ed
- *
- * @return
- */
- boolean isAnded();
-
- /**
- * Answers a new object that matches the logical OR of this and m
- *
- * @param m
- * @return
- * @throws IllegalStateException
- * if an attempt is made to OR to existing AND-ed conditions
- */
- KeyedMatcherSetI or(KeyedMatcherI m);
-
- /**
- * Answers an iterator over the combined match conditions
- *
- * @return
- */
- Iterable<KeyedMatcherI> getMatchers();
-
- /**
- * Answers true if this object contains no conditions
- *
- * @return
- */
- boolean isEmpty();
-}
--- /dev/null
+##fileformat=VCFv4.2
+##INFO=<ID=AC,Number=A,Type=Integer,Description="Allele count in genotypes, for each ALT allele, in the same order as listed">
+##INFO=<ID=AF,Number=A,Type=Float,Description="Allele Frequency, for each ALT allele, in the same order as listed">
+##INFO=<ID=AF_Female,Number=R,Type=Float,Description="Allele Frequency among Female genotypes, for each ALT allele, in the same order as listed">
+##INFO=<ID=AN,Number=1,Type=Integer,Description="Total number of alleles in called genotypes">
+##INFO=<ID=CSQ,Number=.,Type=String,Description="Consequence annotations from Ensembl VEP. Format: Allele|Consequence|IMPACT|SYMBOL|Gene|Feature_type|Feature|BIOTYPE|PolyPhen">
+##reference=/Homo_sapiens/GRCh38
+#CHROM POS ID REF ALT QUAL FILTER INFO
+5 45051610 . C A 81.96 RF;AC0 AC=1;AF=0.1;AN=0;AF_Female=2;AB_MEDIAN=6.00000e-01;CSQ=A|missense_variant|MODIFIER|WASH7P|gene3|Transcript|transcript3|rna|Benign,A|downstream_gene_variant|MODIFIER|WASH7P|gene3|Transcript|transcript4|mrna|Bad
+5 45051614 . C T 1666.64 RF AC=1;AF=0.2;AN=0;AF_Female=2;AB_MEDIAN=6.00000e-01;CSQ=T|missense_variant|MODIFIER|WASH7P|gene3|Transcript|transcript3|rna|Benign,T|downstream_gene_variant|MODIFIER|WASH7P|gene3|Transcript|transcript4|mrna|Bad
+5 45051618 . CGG C 41.94 AC0 AC=1;AF=0.3;AN=0;AF_Female=2;AB_MEDIAN=6.00000e-01;CSQ=C|missense_variant|MODIFIER|WASH7P|gene3|Transcript|transcript3|rna|Benign,C|downstream_gene_variant|MODIFIER|WASH7P|gene3|Transcript|transcript4|mrna|Bad,CSQ=CGT|missense_variant|MODIFIER|WASH7P|gene3|Transcript|transcript3|rna|Benign,CGT|downstream_gene_variant|MODIFIER|WASH7P|gene3|Transcript|transcript4|mrna|Bad
+5 45051622 . C G,T 224.23 RF;AC0 AC=1,2;AF=0.4,0.5;AN=0;AF_Female=2;AB_MEDIAN=6.00000e-01;CSQ=G|missense_variant|MODIFIER|WASH7P|gene3|Transcript|transcript3|rna|Benign,G|downstream_gene_variant|MODIFIER|WASH7P|gene3|Transcript|transcript4|mrna|Bad,T|missense_variant|MODIFIER|WASH7P|gene3|Transcript|transcript3|rna|Benign,T|downstream_gene_variant|MODIFIER|WASH7P|gene3|Transcript|transcript4|mrna|Bad
+5 45051626 . A AC,G 433.35 RF;AC0 AC=3,4;AF=0.6,0.7;AN=0;AF_Female=2;AB_MEDIAN=6.00000e-01;CSQ=G|missense_variant|MODIFIER|WASH7P|gene3|Transcript|transcript3|rna|Benign,G|downstream_gene_variant|MODIFIER|WASH7P|gene3|Transcript|transcript4|mrna|Bad,AC|missense_variant|MODIFIER|WASH7P|gene3|Transcript|transcript3|rna|Benign,AC|downstream_gene_variant|MODIFIER|WASH7P|gene3|Transcript|transcript4|mrna|Bad
+++ /dev/null
-package jalview.util.matcher;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Iterator;
-import java.util.function.Function;
-
-import org.testng.annotations.Test;
-
-public class KeyedMatcherSetTest
-{
- @Test(groups = "Functional")
- public void testMatches()
- {
- /*
- * a numeric matcher - MatcherTest covers more conditions
- */
- KeyedMatcherI km = new KeyedMatcher(Condition.GE, -2F, "AF");
- KeyedMatcherSetI kms = new KeyedMatcherSet();
- kms.and(km);
- assertTrue(kms.matches(key -> "-2"));
- assertTrue(kms.matches(key -> "-1"));
- assertFalse(kms.matches(key -> "-3"));
- assertFalse(kms.matches(key -> ""));
- assertFalse(kms.matches(key -> "junk"));
- assertFalse(kms.matches(key -> null));
-
- /*
- * a string pattern matcher
- */
- km = new KeyedMatcher(Condition.Contains, "Cat", "AF");
- kms = new KeyedMatcherSet();
- kms.and(km);
- assertTrue(kms
- .matches(key -> "AF".equals(key[0]) ? "raining cats and dogs"
- : "showers"));
- }
-
- @Test(groups = "Functional")
- public void testAnd()
- {
- // condition1: AF value contains "dog" (matches)
- KeyedMatcherI km1 = new KeyedMatcher(Condition.Contains, "dog", "AF");
- // condition 2: CSQ value does not contain "how" (does not match)
- KeyedMatcherI km2 = new KeyedMatcher(Condition.NotContains, "how",
- "CSQ");
-
- Function<String[], String> vp = key -> "AF".equals(key[0])
- ? "raining cats and dogs"
- : "showers";
- assertTrue(km1.matches(vp));
- assertFalse(km2.matches(vp));
-
- KeyedMatcherSetI kms = new KeyedMatcherSet();
- assertTrue(kms.matches(vp)); // if no conditions, then 'all' pass
- kms.and(km1);
- assertTrue(kms.matches(vp));
- kms.and(km2);
- assertFalse(kms.matches(vp));
- }
-
- @Test(groups = "Functional")
- public void testToString()
- {
- KeyedMatcherI km1 = new KeyedMatcher(Condition.LT, 1.2f, "AF");
- assertEquals(km1.toString(), "AF < 1.2");
-
- KeyedMatcher km2 = new KeyedMatcher(Condition.NotContains, "path",
- "CLIN_SIG");
- assertEquals(km2.toString(), "CLIN_SIG Does not contain 'PATH'");
-
- /*
- * AND them
- */
- KeyedMatcherSetI kms = new KeyedMatcherSet();
- assertEquals(kms.toString(), "");
- kms.and(km1);
- assertEquals(kms.toString(), "(AF < 1.2)");
- kms.and(km2);
- assertEquals(kms.toString(),
- "(AF < 1.2) AND (CLIN_SIG Does not contain 'PATH')");
-
- /*
- * OR them
- */
- kms = new KeyedMatcherSet();
- assertEquals(kms.toString(), "");
- kms.or(km1);
- assertEquals(kms.toString(), "(AF < 1.2)");
- kms.or(km2);
- assertEquals(kms.toString(),
- "(AF < 1.2) OR (CLIN_SIG Does not contain 'PATH')");
- }
-
- @Test(groups = "Functional")
- public void testOr()
- {
- // condition1: AF value contains "dog" (matches)
- KeyedMatcherI km1 = new KeyedMatcher(Condition.Contains, "dog", "AF");
- // condition 2: CSQ value does not contain "how" (does not match)
- KeyedMatcherI km2 = new KeyedMatcher(Condition.NotContains, "how",
- "CSQ");
-
- Function<String[], String> vp = key -> "AF".equals(key[0])
- ? "raining cats and dogs"
- : "showers";
- assertTrue(km1.matches(vp));
- assertFalse(km2.matches(vp));
-
- KeyedMatcherSetI kms = new KeyedMatcherSet();
- kms.or(km2);
- assertFalse(kms.matches(vp));
- kms.or(km1);
- assertTrue(kms.matches(vp));
- }
-
- @Test(groups = "Functional")
- public void testIsEmpty()
- {
- KeyedMatcherI km = new KeyedMatcher(Condition.GE, -2F, "AF");
- KeyedMatcherSetI kms = new KeyedMatcherSet();
- assertTrue(kms.isEmpty());
- kms.and(km);
- assertFalse(kms.isEmpty());
- }
-
- @Test(groups = "Functional")
- public void testGetMatchers()
- {
- KeyedMatcherSetI kms = new KeyedMatcherSet();
-
- /*
- * empty iterable:
- */
- Iterator<KeyedMatcherI> iterator = kms.getMatchers().iterator();
- assertFalse(iterator.hasNext());
-
- /*
- * one matcher:
- */
- KeyedMatcherI km1 = new KeyedMatcher(Condition.GE, -2F, "AF");
- kms.and(km1);
- iterator = kms.getMatchers().iterator();
- assertSame(km1, iterator.next());
- assertFalse(iterator.hasNext());
-
- /*
- * two matchers:
- */
- KeyedMatcherI km2 = new KeyedMatcher(Condition.LT, 8F, "AF");
- kms.and(km2);
- iterator = kms.getMatchers().iterator();
- assertSame(km1, iterator.next());
- assertSame(km2, iterator.next());
- assertFalse(iterator.hasNext());
- }
-
- /**
- * Tests for the 'compound attribute' key i.e. where first key's value is a map
- * from which we take the value for the second key, e.g. CSQ : Consequence
- */
- @Test(groups = "Functional")
- public void testMatches_compoundKey()
- {
- /*
- * a numeric matcher - MatcherTest covers more conditions
- */
- KeyedMatcherI km = new KeyedMatcher(Condition.GE, -2F, "CSQ",
- "Consequence");
- KeyedMatcherSetI kms = new KeyedMatcherSet();
- kms.and(km);
- assertTrue(kms.matches(key -> "-2"));
- assertTrue(kms.matches(key -> "-1"));
- assertFalse(kms.matches(key -> "-3"));
- assertFalse(kms.matches(key -> ""));
- assertFalse(kms.matches(key -> "junk"));
- assertFalse(kms.matches(key -> null));
-
- /*
- * a string pattern matcher
- */
- km = new KeyedMatcher(Condition.Contains, "Cat", "CSQ", "Consequence");
- kms = new KeyedMatcherSet();
- kms.and(km);
- assertTrue(kms.matches(key -> "csq".equalsIgnoreCase(key[0])
- && "Consequence".equalsIgnoreCase(key[1])
- ? "raining cats and dogs"
- : "showers"));
- }
-}
+++ /dev/null
-package jalview.util.matcher;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import org.testng.annotations.Test;
-
-public class KeyedMatcherTest
-{
- @Test
- public void testMatches()
- {
- /*
- * a numeric matcher - MatcherTest covers more conditions
- */
- KeyedMatcherI km = new KeyedMatcher(Condition.GE, -2F, "AF");
- assertTrue(km.matches(key -> "-2"));
- assertTrue(km.matches(key -> "-1"));
- assertFalse(km.matches(key -> "-3"));
- assertFalse(km.matches(key -> ""));
- assertFalse(km.matches(key -> "junk"));
- assertFalse(km.matches(key -> null));
-
- /*
- * a string pattern matcher
- */
- km = new KeyedMatcher(Condition.Contains, "Cat", "AF");
- assertTrue(
- km.matches(key -> "AF".equals(key[0]) ? "raining cats and dogs"
- : "showers"));
- }
-
- @Test
- public void testToString()
- {
- /*
- * toString uses the i18n translation of the enum conditions
- */
- KeyedMatcherI km = new KeyedMatcher(Condition.LT, 1.2f, "AF");
- assertEquals(km.toString(), "AF < 1.2");
-
- /*
- * Present / NotPresent omit the value pattern
- */
- km = new KeyedMatcher(Condition.Present, "", "AF");
- assertEquals(km.toString(), "AF Is present");
- km = new KeyedMatcher(Condition.NotPresent, "", "AF");
- assertEquals(km.toString(), "AF Is not present");
- }
-
- @Test
- public void testGetKey()
- {
- KeyedMatcherI km = new KeyedMatcher(Condition.GE, -2F, "AF");
- assertEquals(km.getKey(), new String[] { "AF" });
-
- /*
- * compound key (attribute / subattribute)
- */
- km = new KeyedMatcher(Condition.GE, -2F, "CSQ", "Consequence");
- assertEquals(km.getKey(), new String[] { "CSQ", "Consequence" });
- }
-
- @Test
- public void testGetMatcher()
- {
- KeyedMatcherI km = new KeyedMatcher(Condition.GE, -2F, "AF");
- assertEquals(km.getMatcher().getCondition(), Condition.GE);
- assertEquals(km.getMatcher().getFloatValue(), -2F);
- assertEquals(km.getMatcher().getPattern(), "-2.0");
- }
-}