From 60c64cd09cca7cae5fe6a5c966bd2d2d1a284217 Mon Sep 17 00:00:00 2001 From: magicDGS Date: Sat, 17 Sep 2016 14:54:27 +0200 Subject: [PATCH 1/8] fixes #371 --- .../htsjdk/variant/variantcontext/CommonInfo.java | 37 ++++++++++++++++++++++ .../variant/variantcontext/VariantContext.java | 4 ++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java b/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java index 88b02fafb..09afb49e8 100644 --- a/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java +++ b/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java @@ -26,6 +26,7 @@ package htsjdk.variant.variantcontext; +import htsjdk.tribble.util.ParsingUtils; import htsjdk.variant.vcf.VCFConstants; import java.io.Serializable; @@ -37,6 +38,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; /** @@ -255,6 +258,40 @@ public Object getAttribute(String key, Object defaultValue) { return Collections.singletonList(o); } + private List getAttributeAsList(String key, Function transformer) { + return getAttributeAsList(key).stream().map(transformer).collect(Collectors.toList()); + } + + public List getAttributeAsStringList(String key, String defaultValue) { + return getAttributeAsList(key, x -> (x == null) ? defaultValue : String.valueOf(x)); + } + + public List getAttributeAsIntList(String key, int defaultValue) { + return getAttributeAsList(key, x -> { + if (x == null || x == VCFConstants.MISSING_VALUE_v4) { + return defaultValue; + } else if (x instanceof Integer) { + return (Integer) x; + } else { + return Integer.valueOf((String)x); // throws an exception if this isn't a string + } + } + ); + } + + public List getAttributeAsDoubleList(String key, Double defaultValue) { + return getAttributeAsList(key, x -> { + if (x == null || x == VCFConstants.MISSING_VALUE_v4) { + return defaultValue; + } else if (x instanceof Double) { + return (Double) x; + } else { + return Double.valueOf((String)x); // throws an exception if this isn't a string + } + } + ); + } + public String getAttributeAsString(String key, String defaultValue) { Object x = getAttribute(key); if ( x == null ) return defaultValue; diff --git a/src/main/java/htsjdk/variant/variantcontext/VariantContext.java b/src/main/java/htsjdk/variant/variantcontext/VariantContext.java index 0baf0bd70..5c94bff24 100644 --- a/src/main/java/htsjdk/variant/variantcontext/VariantContext.java +++ b/src/main/java/htsjdk/variant/variantcontext/VariantContext.java @@ -747,7 +747,9 @@ public Object getAttribute(String key, Object defaultValue) { as a java.util.List if the value is a List or an Array, as a Collections.singletonList if there is only one value */ public List getAttributeAsList(String key) { return commonInfo.getAttributeAsList(key); } - + public List getAttributeAsStringList(String key, String defaultValue) { return commonInfo.getAttributeAsStringList(key, defaultValue); } + public List getAttributeAsIntList(String key, int defaultValue) { return commonInfo.getAttributeAsIntList(key, defaultValue); } + public List getAttributeAsDoubleList(String key, double defaultValue) { return commonInfo.getAttributeAsDoubleList(key, defaultValue); } public CommonInfo getCommonInfo() { return commonInfo; } From aa71943a7856c9e88553046568bff4658f857864 Mon Sep 17 00:00:00 2001 From: magicDGS Date: Sat, 17 Sep 2016 15:31:06 +0200 Subject: [PATCH 2/8] removed unused imports --- src/main/java/htsjdk/variant/variantcontext/CommonInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java b/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java index 09afb49e8..0710a0544 100644 --- a/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java +++ b/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java @@ -26,7 +26,7 @@ package htsjdk.variant.variantcontext; -import htsjdk.tribble.util.ParsingUtils; + import htsjdk.variant.vcf.VCFConstants; import java.io.Serializable; From c370944b2696e91116edaf64e6b54c02e063fd65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20G=C3=B3mez-S=C3=A1nchez?= Date: Tue, 27 Sep 2016 14:55:37 +0200 Subject: [PATCH 3/8] unit tests + solved bug in getAttributesAsList with primitive arrays --- .../htsjdk/variant/variantcontext/CommonInfo.java | 21 ++++--- .../variantcontext/VariantContextUnitTest.java | 68 +++++++++++++++++++++- 2 files changed, 81 insertions(+), 8 deletions(-) diff --git a/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java b/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java index 0710a0544..da518e63b 100644 --- a/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java +++ b/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java @@ -26,7 +26,6 @@ package htsjdk.variant.variantcontext; - import htsjdk.variant.vcf.VCFConstants; import java.io.Serializable; @@ -40,6 +39,7 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; /** @@ -254,7 +254,14 @@ public Object getAttribute(String key, Object defaultValue) { Object o = getAttribute(key); if ( o == null ) return Collections.emptyList(); if ( o instanceof List ) return (List)o; - if ( o.getClass().isArray() ) return Arrays.asList((Object[])o); + if ( o.getClass().isArray() ) { + if (o instanceof int[]) { + return Arrays.stream((int[])o).boxed().collect(Collectors.toList()); + } else if (o instanceof double[]) { + return Arrays.stream((double[])o).boxed().collect(Collectors.toList()); + } + return Arrays.asList((Object[])o); + } return Collections.singletonList(o); } @@ -266,12 +273,12 @@ public Object getAttribute(String key, Object defaultValue) { return getAttributeAsList(key, x -> (x == null) ? defaultValue : String.valueOf(x)); } - public List getAttributeAsIntList(String key, int defaultValue) { + public List getAttributeAsIntList(String key, Integer defaultValue) { return getAttributeAsList(key, x -> { if (x == null || x == VCFConstants.MISSING_VALUE_v4) { return defaultValue; - } else if (x instanceof Integer) { - return (Integer) x; + } else if (x instanceof Number) { + return ((Number) x).intValue(); } else { return Integer.valueOf((String)x); // throws an exception if this isn't a string } @@ -283,8 +290,8 @@ public Object getAttribute(String key, Object defaultValue) { return getAttributeAsList(key, x -> { if (x == null || x == VCFConstants.MISSING_VALUE_v4) { return defaultValue; - } else if (x instanceof Double) { - return (Double) x; + } else if (x instanceof Number) { + return ((Number) x).doubleValue(); } else { return Double.valueOf((String)x); // throws an exception if this isn't a string } diff --git a/src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java b/src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java index 34854eaea..89d2a13a9 100644 --- a/src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java +++ b/src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java @@ -38,7 +38,6 @@ import htsjdk.variant.bcf2.BCF2Codec; import htsjdk.variant.vcf.VCFCodec; import htsjdk.tribble.TribbleException; -import htsjdk.variant.VariantBaseTest; import htsjdk.variant.vcf.VCFConstants; import htsjdk.variant.vcf.VCFFileReader; @@ -1478,4 +1477,71 @@ public void testExtractStructuralVariationsData(final File vcfFile) { CloserUtil.close(reader); } } + + @Test + public void testGetAttributeAsIntList() { + final VariantContext context = basicBuilder + .attribute("DefaultIntegerList", new int[5]) + .attribute("ListWithMissing", new Object[]{1, null, null}) + .attribute("IntegerList", new int[]{0, 1, 2, 3}) + .attribute("DoubleList", new double[]{1.8, 1.6, 2.1}) + .attribute("StringList", new String[]{"1", "2"}) + .attribute("NotNumeric", new String[]{"A", "B"}) + .make(); + // test as integer + Assert.assertEquals(context.getAttributeAsIntList("DefaultIntegerList", 5), Arrays.asList(0, 0, 0, 0, 0)); + Assert.assertEquals(context.getAttributeAsIntList("ListWithMissing", 5), Arrays.asList(1, 5, 5)); + Assert.assertEquals(context.getAttributeAsIntList("IntegerList", 5), Arrays.asList(0, 1, 2, 3)); + Assert.assertEquals(context.getAttributeAsIntList("DoubleList", 5), Arrays.asList(1, 1, 2)); + Assert.assertEquals(context.getAttributeAsIntList("StringList", 5), Arrays.asList(1, 2)); + try { + context.getAttributeAsIntList("NotNumeric", 5); + Assert.fail(); + } catch (Exception e) { + + } + } + + @Test + public void testGetAttributeAsDoubleList() { + final VariantContext context = basicBuilder + .attribute("DefaultIntegerList", new int[5]) + .attribute("ListWithMissing", new Object[]{1, null, null}) + .attribute("IntegerList", new int[]{0, 1, 2, 3}) + .attribute("DoubleList", new double[]{1.8, 1.6, 2.1}) + .attribute("StringList", new String[]{"1", "2"}) + .attribute("NotNumeric", new String[]{"A", "B"}) + .make(); + // test as integer + Assert.assertEquals(context.getAttributeAsDoubleList("DefaultIntegerList", 5), Arrays.asList(0d, 0d, 0d, 0d, 0d)); + Assert.assertEquals(context.getAttributeAsDoubleList("ListWithMissing", 5), Arrays.asList(1d, 5d, 5d)); + Assert.assertEquals(context.getAttributeAsDoubleList("IntegerList", 5), Arrays.asList(0d, 1d, 2d, 3d)); + Assert.assertEquals(context.getAttributeAsDoubleList("DoubleList", 5), Arrays.asList(1.8, 1.6, 2.1)); + Assert.assertEquals(context.getAttributeAsDoubleList("StringList", 5), Arrays.asList(1d, 2d)); + try { + context.getAttributeAsIntList("NotNumeric", 5); + Assert.fail(); + } catch (Exception e) { + + } + } + + @Test + public void testGetAttributeAsStringList() { + final VariantContext context = basicBuilder + .attribute("DefaultIntegerList", new int[5]) + .attribute("ListWithMissing", new Object[]{1, null, null}) + .attribute("IntegerList", new int[]{0, 1, 2, 3}) + .attribute("DoubleList", new double[]{1.8, 1.6, 2.1}) + .attribute("StringList", new String[]{"1", "2"}) + .attribute("NotNumeric", new String[]{"A", "B"}) + .make(); + // test as integer + Assert.assertEquals(context.getAttributeAsStringList("DefaultIntegerList", "empty"), Arrays.asList("0", "0", "0", "0", "0")); + Assert.assertEquals(context.getAttributeAsStringList("ListWithMissing", "empty"), Arrays.asList("1", "empty", "empty")); + Assert.assertEquals(context.getAttributeAsStringList("IntegerList", "empty"), Arrays.asList("0", "1", "2", "3")); + Assert.assertEquals(context.getAttributeAsStringList("DoubleList", "empty"), Arrays.asList("1.8", "1.6", "2.1")); + Assert.assertEquals(context.getAttributeAsStringList("StringList", "empty"), Arrays.asList("1", "2")); + Assert.assertEquals(context.getAttributeAsStringList("NotNumeric", "empty"), Arrays.asList("A", "B")); + } } From 243031cd949ab1afda7c99e02b6992f19ade90d3 Mon Sep 17 00:00:00 2001 From: magicDGS Date: Tue, 8 Nov 2016 00:05:36 +0100 Subject: [PATCH 4/8] added documentation about primitive arrays --- src/main/java/htsjdk/variant/variantcontext/CommonInfo.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java b/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java index da518e63b..e4920df94 100644 --- a/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java +++ b/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java @@ -40,6 +40,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import java.util.stream.StreamSupport; /** @@ -248,7 +249,16 @@ public Object getAttribute(String key, Object defaultValue) { /** returns the value as an empty list if the key was not found, as a java.util.List if the value is a List or an Array, - as a Collections.singletonList if there is only one value */ + as a Collections.singletonList if there is only one value + */ + /** + * Gets the attributes from a key as a list. + * + * Note: int[] and double[] arrays are boxed. + * + * @return empty list if the key was not found; {@link Collections#singletonList(Object)} if + * there is only one value; a list containing the values if the value is a {@link List} or array. + */ @SuppressWarnings("unchecked") public List getAttributeAsList(String key) { Object o = getAttribute(key); From 4db74d70b545efdaeeba228ea983dc92b1e89d49 Mon Sep 17 00:00:00 2001 From: magicDGS Date: Tue, 8 Nov 2016 00:07:21 +0100 Subject: [PATCH 5/8] removing extra indents --- .../htsjdk/variant/variantcontext/CommonInfo.java | 25 ++++++++-------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java b/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java index e4920df94..d8a61961a 100644 --- a/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java +++ b/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java @@ -39,8 +39,6 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; /** @@ -246,11 +244,7 @@ public Object getAttribute(String key, Object defaultValue) { else return defaultValue; } - - /** returns the value as an empty list if the key was not found, - as a java.util.List if the value is a List or an Array, - as a Collections.singletonList if there is only one value - */ + /** * Gets the attributes from a key as a list. * @@ -285,15 +279,14 @@ public Object getAttribute(String key, Object defaultValue) { public List getAttributeAsIntList(String key, Integer defaultValue) { return getAttributeAsList(key, x -> { - if (x == null || x == VCFConstants.MISSING_VALUE_v4) { - return defaultValue; - } else if (x instanceof Number) { - return ((Number) x).intValue(); - } else { - return Integer.valueOf((String)x); // throws an exception if this isn't a string - } - } - ); + if (x == null || x == VCFConstants.MISSING_VALUE_v4) { + return defaultValue; + } else if (x instanceof Number) { + return ((Number) x).intValue(); + } else { + return Integer.valueOf((String)x); // throws an exception if this isn't a string + } + }); } public List getAttributeAsDoubleList(String key, Double defaultValue) { From 8b79661c47f2603d791ca4b5fdd803702536838d Mon Sep 17 00:00:00 2001 From: magicDGS Date: Sun, 20 Nov 2016 13:04:55 +0100 Subject: [PATCH 6/8] removed extra indent --- .../htsjdk/variant/variantcontext/CommonInfo.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java b/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java index d8a61961a..e2f9083cf 100644 --- a/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java +++ b/src/main/java/htsjdk/variant/variantcontext/CommonInfo.java @@ -244,7 +244,7 @@ public Object getAttribute(String key, Object defaultValue) { else return defaultValue; } - + /** * Gets the attributes from a key as a list. * @@ -291,15 +291,14 @@ public Object getAttribute(String key, Object defaultValue) { public List getAttributeAsDoubleList(String key, Double defaultValue) { return getAttributeAsList(key, x -> { - if (x == null || x == VCFConstants.MISSING_VALUE_v4) { - return defaultValue; - } else if (x instanceof Number) { - return ((Number) x).doubleValue(); - } else { - return Double.valueOf((String)x); // throws an exception if this isn't a string - } - } - ); + if (x == null || x == VCFConstants.MISSING_VALUE_v4) { + return defaultValue; + } else if (x instanceof Number) { + return ((Number) x).doubleValue(); + } else { + return Double.valueOf((String)x); // throws an exception if this isn't a string + } + }); } public String getAttributeAsString(String key, String defaultValue) { From f0b15d1fc120ad17ae7d812b7707cd70a0237474 Mon Sep 17 00:00:00 2001 From: magicDGS Date: Sun, 20 Nov 2016 13:16:47 +0100 Subject: [PATCH 7/8] more tests --- .../variantcontext/VariantContextUnitTest.java | 33 +++++++++++++--------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java b/src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java index 89d2a13a9..84f38096b 100644 --- a/src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java +++ b/src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java @@ -1481,6 +1481,7 @@ public void testExtractStructuralVariationsData(final File vcfFile) { @Test public void testGetAttributeAsIntList() { final VariantContext context = basicBuilder + .attribute("Empty", new int[0]) .attribute("DefaultIntegerList", new int[5]) .attribute("ListWithMissing", new Object[]{1, null, null}) .attribute("IntegerList", new int[]{0, 1, 2, 3}) @@ -1488,23 +1489,23 @@ public void testGetAttributeAsIntList() { .attribute("StringList", new String[]{"1", "2"}) .attribute("NotNumeric", new String[]{"A", "B"}) .make(); + // test an empty value + Assert.assertTrue(context.getAttributeAsIntList("Empty", 5).isEmpty()); // test as integer Assert.assertEquals(context.getAttributeAsIntList("DefaultIntegerList", 5), Arrays.asList(0, 0, 0, 0, 0)); Assert.assertEquals(context.getAttributeAsIntList("ListWithMissing", 5), Arrays.asList(1, 5, 5)); Assert.assertEquals(context.getAttributeAsIntList("IntegerList", 5), Arrays.asList(0, 1, 2, 3)); Assert.assertEquals(context.getAttributeAsIntList("DoubleList", 5), Arrays.asList(1, 1, 2)); Assert.assertEquals(context.getAttributeAsIntList("StringList", 5), Arrays.asList(1, 2)); - try { - context.getAttributeAsIntList("NotNumeric", 5); - Assert.fail(); - } catch (Exception e) { - - } + Assert.assertThrows(() -> context.getAttributeAsIntList("NotNumeric", 5)); + // test the case of a missing key + Assert.assertTrue(context.getAttributeAsIntList("MissingList", 5).isEmpty()); } @Test public void testGetAttributeAsDoubleList() { final VariantContext context = basicBuilder + .attribute("Empty", new int[0]) .attribute("DefaultIntegerList", new int[5]) .attribute("ListWithMissing", new Object[]{1, null, null}) .attribute("IntegerList", new int[]{0, 1, 2, 3}) @@ -1512,23 +1513,23 @@ public void testGetAttributeAsDoubleList() { .attribute("StringList", new String[]{"1", "2"}) .attribute("NotNumeric", new String[]{"A", "B"}) .make(); - // test as integer + // test an empty value + Assert.assertTrue(context.getAttributeAsDoubleList("Empty", 5).isEmpty()); + // test as double Assert.assertEquals(context.getAttributeAsDoubleList("DefaultIntegerList", 5), Arrays.asList(0d, 0d, 0d, 0d, 0d)); Assert.assertEquals(context.getAttributeAsDoubleList("ListWithMissing", 5), Arrays.asList(1d, 5d, 5d)); Assert.assertEquals(context.getAttributeAsDoubleList("IntegerList", 5), Arrays.asList(0d, 1d, 2d, 3d)); Assert.assertEquals(context.getAttributeAsDoubleList("DoubleList", 5), Arrays.asList(1.8, 1.6, 2.1)); Assert.assertEquals(context.getAttributeAsDoubleList("StringList", 5), Arrays.asList(1d, 2d)); - try { - context.getAttributeAsIntList("NotNumeric", 5); - Assert.fail(); - } catch (Exception e) { - - } + Assert.assertThrows(() -> context.getAttributeAsDoubleList("NotNumeric", 5)); + // test the case of a missing key + Assert.assertTrue(context.getAttributeAsDoubleList("MissingList", 5).isEmpty()); } @Test public void testGetAttributeAsStringList() { final VariantContext context = basicBuilder + .attribute("Empty", new int[0]) .attribute("DefaultIntegerList", new int[5]) .attribute("ListWithMissing", new Object[]{1, null, null}) .attribute("IntegerList", new int[]{0, 1, 2, 3}) @@ -1536,12 +1537,16 @@ public void testGetAttributeAsStringList() { .attribute("StringList", new String[]{"1", "2"}) .attribute("NotNumeric", new String[]{"A", "B"}) .make(); - // test as integer + // test an empty value + Assert.assertTrue(context.getAttributeAsStringList("Empty", "empty").isEmpty()); + // test as string Assert.assertEquals(context.getAttributeAsStringList("DefaultIntegerList", "empty"), Arrays.asList("0", "0", "0", "0", "0")); Assert.assertEquals(context.getAttributeAsStringList("ListWithMissing", "empty"), Arrays.asList("1", "empty", "empty")); Assert.assertEquals(context.getAttributeAsStringList("IntegerList", "empty"), Arrays.asList("0", "1", "2", "3")); Assert.assertEquals(context.getAttributeAsStringList("DoubleList", "empty"), Arrays.asList("1.8", "1.6", "2.1")); Assert.assertEquals(context.getAttributeAsStringList("StringList", "empty"), Arrays.asList("1", "2")); Assert.assertEquals(context.getAttributeAsStringList("NotNumeric", "empty"), Arrays.asList("A", "B")); + // test the case of a missing key + Assert.assertTrue(context.getAttributeAsStringList("MissingList", "empy").isEmpty()); } } From 9cfe0cd2a3c87bd209b60828d88f1f5d386625d3 Mon Sep 17 00:00:00 2001 From: magicDGS Date: Sun, 20 Nov 2016 14:09:41 +0100 Subject: [PATCH 8/8] fixed typo --- src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java b/src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java index 84f38096b..32e5596b5 100644 --- a/src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java +++ b/src/test/java/htsjdk/variant/variantcontext/VariantContextUnitTest.java @@ -1547,6 +1547,6 @@ public void testGetAttributeAsStringList() { Assert.assertEquals(context.getAttributeAsStringList("StringList", "empty"), Arrays.asList("1", "2")); Assert.assertEquals(context.getAttributeAsStringList("NotNumeric", "empty"), Arrays.asList("A", "B")); // test the case of a missing key - Assert.assertTrue(context.getAttributeAsStringList("MissingList", "empy").isEmpty()); + Assert.assertTrue(context.getAttributeAsStringList("MissingList", "empty").isEmpty()); } }