From 8971b54b21001846ba3cfc0a2af603f159a48c91 Mon Sep 17 00:00:00 2001 From: Mark DePristo Date: Wed, 28 Mar 2012 14:18:56 -0400 Subject: [PATCH] Phase II of Stratification manager -- Renamed and reorganized infrastructure -- StratificationManager now a Map from List -> V. All key functions are implemented. Less commonly used TODO -- Ready for hookup to VE --- .../stratifications/StratificationStates.java | 101 -------- .../{ => manager}/SetOfStates.java | 2 +- .../{ => manager}/StratNode.java | 5 +- .../{ => manager}/StratNodeIterator.java | 2 +- .../manager/StratificationManager.java | 230 ++++++++++++++++++ .../StratificationManagerUnitTest.java} | 66 +++-- 6 files changed, 285 insertions(+), 121 deletions(-) delete mode 100644 public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratificationStates.java rename public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/{ => manager}/SetOfStates.java (98%) rename public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/{ => manager}/StratNode.java (97%) rename public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/{ => manager}/StratNodeIterator.java (99%) create mode 100644 public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratificationManager.java rename public/java/test/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/{StratificationStatesUnitTest.java => manager/StratificationManagerUnitTest.java} (74%) diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratificationStates.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratificationStates.java deleted file mode 100644 index b6ee7d807..000000000 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratificationStates.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2012, The Broad Institute - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -package org.broadinstitute.sting.gatk.walkers.varianteval.stratifications; - -import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; - -import java.util.*; - -/** - * Represents the full state space of all stratification combinations - * - * @author Mark DePristo - * @since 3/27/12 - */ -public class StratificationStates { - private final StratNode root; - - public StratificationStates(final List strats) { - this.root = buildStratificationTree(new LinkedList(strats)); - - assignKeys(root, 0); - } - - private StratNode buildStratificationTree(final Queue strats) { - final T first = strats.poll(); - if ( first == null ) { - // we are at a leaf - return new StratNode(); - } else { - // we are in the middle of the tree - final Collection states = first.getAllStates(); - final LinkedHashMap> subNodes = new LinkedHashMap>(states.size()); - for ( final Object state : states ) { - // have to copy because poll modifies the queue - final Queue copy = new LinkedList(strats); - subNodes.put(state, buildStratificationTree(copy)); - } - return new StratNode(first, subNodes); - } - } - - public int getNStates() { - return root.size(); - } - - public StratNode getRoot() { - return root; - } - - public int getKey(final List states) { - return root.find(states, 0); - } - - public Set getKeys(final List> allStates) { - final HashSet keys = new HashSet(); - root.find(allStates, 0, keys); - return keys; - } - - private void assignKeys(final StratNode root, int key) { - for ( final StratNode node : root ) { - if ( node.isLeaf() ) - node.setKey(key++); - } - } - - public static List> combineStates(final List first, final List second) { - List> combined = new ArrayList>(first.size()); - for ( int i = 0; i < first.size(); i++ ) { - final Object firstI = first.get(i); - final Object secondI = second.get(i); - if ( firstI.equals(secondI) ) - combined.add(Collections.singletonList(firstI)); - else - combined.add(Arrays.asList(firstI, secondI)); - } - return combined; - } -} diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/SetOfStates.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/SetOfStates.java similarity index 98% rename from public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/SetOfStates.java rename to public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/SetOfStates.java index 30b432c63..7a65e62af 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/SetOfStates.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/SetOfStates.java @@ -22,7 +22,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -package org.broadinstitute.sting.gatk.walkers.varianteval.stratifications; +package org.broadinstitute.sting.gatk.walkers.varianteval.stratifications.manager; import java.util.List; diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratNode.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratNode.java similarity index 97% rename from public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratNode.java rename to public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratNode.java index f350df47d..b82fd2bc4 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratNode.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratNode.java @@ -22,7 +22,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -package org.broadinstitute.sting.gatk.walkers.varianteval.stratifications; +package org.broadinstitute.sting.gatk.walkers.varianteval.stratifications.manager; import com.google.java.contract.Ensures; import com.google.java.contract.Invariant; @@ -62,6 +62,7 @@ import java.util.*; class StratNode implements Iterable> { int key = -1; final T stratifier; + // TODO -- track state key that maps to root node final Map> subnodes; protected StratNode() { @@ -93,7 +94,7 @@ class StratNode implements Iterable> { final Object state = states.get(offset); StratNode subnode = subnodes.get(state); if ( subnode == null ) - throw new ReviewedStingException("Couldn't find state for " + state + " at node " + this); + return -1; else return subnode.find(states, offset+1); } diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratNodeIterator.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratNodeIterator.java similarity index 99% rename from public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratNodeIterator.java rename to public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratNodeIterator.java index 17aa88387..cda30a0c9 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratNodeIterator.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratNodeIterator.java @@ -22,7 +22,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -package org.broadinstitute.sting.gatk.walkers.varianteval.stratifications; +package org.broadinstitute.sting.gatk.walkers.varianteval.stratifications.manager; import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratificationManager.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratificationManager.java new file mode 100644 index 000000000..12bd0df57 --- /dev/null +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratificationManager.java @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2012, The Broad Institute + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.broadinstitute.sting.gatk.walkers.varianteval.stratifications.manager; + +import com.google.java.contract.Ensures; +import com.google.java.contract.Requires; +import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; + +import java.util.*; + +/** + * Represents the full state space of all stratification combinations + * + * @author Mark DePristo + * @since 3/27/12 + */ +public class StratificationManager implements Map, V> { + private final StratNode root; + private final int size; + private final ArrayList values; + + // ------------------------------------------------------------------------------------- + // + // creating the manager + // + // ------------------------------------------------------------------------------------- + + @Requires("!strats.isEmpty()") + public StratificationManager(final List strats) { + this.root = buildStratificationTree(new LinkedList(strats)); + assignKeys(root); + this.size = root.size(); + if ( this.size == 0 ) + throw new ReviewedStingException("Size == 0 in StratificationManager"); + + this.values = new ArrayList(size()); + for ( int i = 0; i < size(); i++ ) + this.values().add(null); + } + + private StratNode buildStratificationTree(final Queue strats) { + final K first = strats.poll(); + if ( first == null ) { + // we are at a leaf + return new StratNode(); + } else { + // we are in the middle of the tree + final Collection states = first.getAllStates(); + + if ( states.isEmpty() ) + throw new ReviewedStingException("State " + first + " is empty!"); + + final LinkedHashMap> subNodes = new LinkedHashMap>(states.size()); + for ( final Object state : states ) { + // have to copy because poll modifies the queue + final Queue copy = new LinkedList(strats); + subNodes.put(state, buildStratificationTree(copy)); + } + return new StratNode(first, subNodes); + } + } + + @Requires("root == this.root") + private void assignKeys(final StratNode root) { + int key = 0; + for ( final StratNode node : root ) { + if ( node.isLeaf() ) + node.setKey(key++); + } + } + + // ------------------------------------------------------------------------------------- + // + // simple accessors + // + // ------------------------------------------------------------------------------------- + + @Ensures("result >= 0") + public int size() { + return size; + } + + @Ensures("result != null") + public StratNode getRoot() { + return root; + } + + // ------------------------------------------------------------------------------------- + // + // mapping from states -> keys + // + // ------------------------------------------------------------------------------------- + + @Requires("states != null") + @Ensures("result >= -1") + public int getKey(final List states) { + return root.find(states, 0); + } + + @Requires("allStates != null") + @Ensures("result != null") + public Set getKeys(final List> allStates) { + final HashSet keys = new HashSet(); + root.find(allStates, 0, keys); + return keys; + } + + // ------------------------------------------------------------------------------------- + // + // values + // + // ------------------------------------------------------------------------------------- + + @Override + @Ensures("result != null") + public ArrayList values() { + return values; + } + + @Requires("key >= 0 && key <= size()") + @Ensures("get(key) == value") + public void set(final int key, final V value) { + values.set(key, value); + } + + @Requires("key >= 0 && key <= size()") + public V get(final int key) { + return values.get(key); + } + + @Requires("getKey(states) != -1") + public V get(final List states) { + return get(getKey(states)); + } + + @Override + public V get(final Object o) { + return get((List)o); + } + + @Override + public boolean isEmpty() { + return false; + } + + public boolean containsKey(final List o) { + return getKey(o) != -1; + } + + @Override + public boolean containsKey(final Object o) { + return containsKey((List)o); + } + + @Override + public boolean containsValue(final Object o) { + throw new ReviewedStingException("containsValue() not implemented for StratificationManager"); + } + + @Override + public V put(final List objects, final V v) { + throw new ReviewedStingException("put() not implemented for StratificationManager"); + } + + @Override + public V remove(final Object o) { + throw new ReviewedStingException("remove() not implemented for StratificationManager"); + } + + @Override + public void putAll(final Map, ? extends V> map) { + throw new ReviewedStingException("clear() not implemented for StratificationManager"); + } + + @Override + public void clear() { + throw new ReviewedStingException("clear() not implemented for StratificationManager"); + } + + @Override + public Set> keySet() { + throw new ReviewedStingException("Not yet implemented"); + } + + @Override + public Set, V>> entrySet() { + throw new ReviewedStingException("Not yet implemented"); + } + + // ------------------------------------------------------------------------------------- + // + // utilities + // + // ------------------------------------------------------------------------------------- + + public static List> combineStates(final List first, final List second) { + List> combined = new ArrayList>(first.size()); + for ( int i = 0; i < first.size(); i++ ) { + final Object firstI = first.get(i); + final Object secondI = second.get(i); + if ( firstI.equals(secondI) ) + combined.add(Collections.singletonList(firstI)); + else + combined.add(Arrays.asList(firstI, secondI)); + } + return combined; + } +} diff --git a/public/java/test/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratificationStatesUnitTest.java b/public/java/test/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratificationManagerUnitTest.java similarity index 74% rename from public/java/test/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratificationStatesUnitTest.java rename to public/java/test/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratificationManagerUnitTest.java index d6291b812..93db1f9ad 100644 --- a/public/java/test/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/StratificationStatesUnitTest.java +++ b/public/java/test/org/broadinstitute/sting/gatk/walkers/varianteval/stratifications/manager/StratificationManagerUnitTest.java @@ -23,7 +23,7 @@ */ // our package -package org.broadinstitute.sting.gatk.walkers.varianteval.stratifications; +package org.broadinstitute.sting.gatk.walkers.varianteval.stratifications.manager; // the imports for unit testing. @@ -40,7 +40,7 @@ import java.io.FileNotFoundException; import java.util.*; -public class StratificationStatesUnitTest extends BaseTest { +public class StratificationManagerUnitTest extends BaseTest { @BeforeClass public void init() throws FileNotFoundException { } @@ -83,6 +83,13 @@ public class StratificationStatesUnitTest extends BaseTest { return asSetOfStates; } + public ArrayList values() { + final ArrayList l = new ArrayList(); + for ( int i = 0; i < nStates; i++ ) + l.add(i); + return l; + } + public Queue> getAllCombinations() { return getAllCombinations(new LinkedList>(allStates)); } @@ -136,15 +143,26 @@ public class StratificationStatesUnitTest extends BaseTest { new StratificationStatesTestProvider(Arrays.asList(0, 1), Arrays.asList(2, 3), Arrays.asList(4, 5), Arrays.asList(6, 7)); return StratificationStatesTestProvider.getTests(StratificationStatesTestProvider.class); } + + private final StratificationManager createManager(StratificationStatesTestProvider cfg) { + final StratificationManager manager = new StratificationManager(cfg.getStateSpaceList()); + List values = cfg.values(); + for ( int i = 0; i < cfg.nStates; i++ ) + manager.set(i, values.get(i)); + + Assert.assertEquals(manager.values(), values, "Values not equal"); + + return manager; + } @Test(dataProvider = "StratificationStatesTestProvider") public void testLeafCount(StratificationStatesTestProvider cfg) { - final StratificationStates stratificationStates = new StratificationStates(cfg.getStateSpaceList()); - - Assert.assertEquals(stratificationStates.getNStates(), cfg.nStates); + final StratificationManager stratificationManager = createManager(cfg); + + Assert.assertEquals(stratificationManager.size(), cfg.nStates); int nLeafs = 0; - for ( final StratNode node : stratificationStates.getRoot() ) { + for ( final StratNode node : stratificationManager.getRoot() ) { if ( node.isLeaf() ) nLeafs++; } @@ -153,9 +171,9 @@ public class StratificationStatesUnitTest extends BaseTest { @Test(dataProvider = "StratificationStatesTestProvider") public void testKeys(StratificationStatesTestProvider cfg) { - final StratificationStates stratificationStates = new StratificationStates(cfg.getStateSpaceList()); + final StratificationManager stratificationManager = createManager(cfg); final Set seenKeys = new HashSet(cfg.nStates); - for ( final StratNode node : stratificationStates.getRoot() ) { + for ( final StratNode node : stratificationManager.getRoot() ) { if ( node.isLeaf() ) { Assert.assertFalse(seenKeys.contains(node.getKey()), "Already seen the key"); seenKeys.add(node.getKey()); @@ -165,20 +183,29 @@ public class StratificationStatesUnitTest extends BaseTest { @Test(dataProvider = "StratificationStatesTestProvider") public void testFindSingleKeys(StratificationStatesTestProvider cfg) { - final StratificationStates stratificationStates = new StratificationStates(cfg.getStateSpaceList()); + final StratificationManager stratificationManager = createManager(cfg); final Set seenKeys = new HashSet(cfg.nStates); for ( List state : cfg.getAllCombinations() ) { - final int key = stratificationStates.getKey(state); + final int key = stratificationManager.getKey(state); Assert.assertFalse(seenKeys.contains(key), "Already saw state mapping to this key"); + Assert.assertTrue(stratificationManager.containsKey(state)); seenKeys.add(key); + + // test value + Assert.assertEquals(stratificationManager.get(key), cfg.values().get(key)); + Assert.assertEquals(stratificationManager.get(state), cfg.values().get(key)); + + state.set(0, 12345); // not present + Assert.assertEquals(stratificationManager.getKey(state), -1); + Assert.assertFalse(stratificationManager.containsKey(state)); } } @Test(dataProvider = "StratificationStatesTestProvider") public void testFindMultipleKeys(StratificationStatesTestProvider cfg) { - final StratificationStates stratificationStates = new StratificationStates(cfg.getStateSpaceList()); + final StratificationManager stratificationManager = createManager(cfg); final List> states = new ArrayList>(cfg.allStates); - final Set keys = stratificationStates.getKeys(states); + final Set keys = stratificationManager.getKeys(states); Assert.assertEquals(keys.size(), cfg.nStates, "Find all states didn't find all of the expected unique keys"); final Queue> combinations = cfg.getAllCombinations(); @@ -186,12 +213,12 @@ public class StratificationStatesUnitTest extends BaseTest { List first = combinations.poll(); List second = combinations.peek(); if ( second != null ) { - List> combined = StratificationStates.combineStates(first, second); + List> combined = StratificationManager.combineStates(first, second); int nExpectedKeys = Utils.nCombinations(combined); - final int key1 = stratificationStates.getKey(first); - final int key2 = stratificationStates.getKey(second); - final Set keysCombined = stratificationStates.getKeys(combined); + final int key1 = stratificationManager.getKey(first); + final int key2 = stratificationManager.getKey(second); + final Set keysCombined = stratificationManager.getKeys(combined); Assert.assertTrue(keysCombined.contains(key1), "couldn't find key in data set"); Assert.assertTrue(keysCombined.contains(key2), "couldn't find key in data set"); @@ -200,4 +227,11 @@ public class StratificationStatesUnitTest extends BaseTest { } } } + + @Test(dataProvider = "StratificationStatesTestProvider") + public void testMapSet(StratificationStatesTestProvider cfg) { + final StratificationManager stratificationManager = createManager(cfg); + stratificationManager.set(0, -1); + Assert.assertEquals((int)stratificationManager.get(0), -1); + } } \ No newline at end of file