Phase II of Stratification manager
-- Renamed and reorganized infrastructure -- StratificationManager now a Map from List<Object> -> V. All key functions are implemented. Less commonly used TODO -- Ready for hookup to VE
This commit is contained in:
parent
9f1cd0ff66
commit
8971b54b21
|
|
@ -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<T extends SetOfStates> {
|
||||
private final StratNode<T> root;
|
||||
|
||||
public StratificationStates(final List<T> strats) {
|
||||
this.root = buildStratificationTree(new LinkedList<T>(strats));
|
||||
|
||||
assignKeys(root, 0);
|
||||
}
|
||||
|
||||
private StratNode<T> buildStratificationTree(final Queue<T> strats) {
|
||||
final T first = strats.poll();
|
||||
if ( first == null ) {
|
||||
// we are at a leaf
|
||||
return new StratNode<T>();
|
||||
} else {
|
||||
// we are in the middle of the tree
|
||||
final Collection<Object> states = first.getAllStates();
|
||||
final LinkedHashMap<Object, StratNode<T>> subNodes = new LinkedHashMap<Object, StratNode<T>>(states.size());
|
||||
for ( final Object state : states ) {
|
||||
// have to copy because poll modifies the queue
|
||||
final Queue<T> copy = new LinkedList<T>(strats);
|
||||
subNodes.put(state, buildStratificationTree(copy));
|
||||
}
|
||||
return new StratNode<T>(first, subNodes);
|
||||
}
|
||||
}
|
||||
|
||||
public int getNStates() {
|
||||
return root.size();
|
||||
}
|
||||
|
||||
public StratNode<T> getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public int getKey(final List<Object> states) {
|
||||
return root.find(states, 0);
|
||||
}
|
||||
|
||||
public Set<Integer> getKeys(final List<List<Object>> allStates) {
|
||||
final HashSet<Integer> keys = new HashSet<Integer>();
|
||||
root.find(allStates, 0, keys);
|
||||
return keys;
|
||||
}
|
||||
|
||||
private void assignKeys(final StratNode<T> root, int key) {
|
||||
for ( final StratNode<T> node : root ) {
|
||||
if ( node.isLeaf() )
|
||||
node.setKey(key++);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<List<Object>> combineStates(final List<Object> first, final List<Object> second) {
|
||||
List<List<Object>> combined = new ArrayList<List<Object>>(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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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<T extends SetOfStates> implements Iterable<StratNode<T>> {
|
||||
int key = -1;
|
||||
final T stratifier;
|
||||
// TODO -- track state key that maps to root node
|
||||
final Map<Object, StratNode<T>> subnodes;
|
||||
|
||||
protected StratNode() {
|
||||
|
|
@ -93,7 +94,7 @@ class StratNode<T extends SetOfStates> implements Iterable<StratNode<T>> {
|
|||
final Object state = states.get(offset);
|
||||
StratNode<T> 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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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<K extends SetOfStates, V> implements Map<List<Object>, V> {
|
||||
private final StratNode<K> root;
|
||||
private final int size;
|
||||
private final ArrayList<V> values;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
//
|
||||
// creating the manager
|
||||
//
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
@Requires("!strats.isEmpty()")
|
||||
public StratificationManager(final List<K> strats) {
|
||||
this.root = buildStratificationTree(new LinkedList<K>(strats));
|
||||
assignKeys(root);
|
||||
this.size = root.size();
|
||||
if ( this.size == 0 )
|
||||
throw new ReviewedStingException("Size == 0 in StratificationManager");
|
||||
|
||||
this.values = new ArrayList<V>(size());
|
||||
for ( int i = 0; i < size(); i++ )
|
||||
this.values().add(null);
|
||||
}
|
||||
|
||||
private StratNode<K> buildStratificationTree(final Queue<K> strats) {
|
||||
final K first = strats.poll();
|
||||
if ( first == null ) {
|
||||
// we are at a leaf
|
||||
return new StratNode<K>();
|
||||
} else {
|
||||
// we are in the middle of the tree
|
||||
final Collection<Object> states = first.getAllStates();
|
||||
|
||||
if ( states.isEmpty() )
|
||||
throw new ReviewedStingException("State " + first + " is empty!");
|
||||
|
||||
final LinkedHashMap<Object, StratNode<K>> subNodes = new LinkedHashMap<Object, StratNode<K>>(states.size());
|
||||
for ( final Object state : states ) {
|
||||
// have to copy because poll modifies the queue
|
||||
final Queue<K> copy = new LinkedList<K>(strats);
|
||||
subNodes.put(state, buildStratificationTree(copy));
|
||||
}
|
||||
return new StratNode<K>(first, subNodes);
|
||||
}
|
||||
}
|
||||
|
||||
@Requires("root == this.root")
|
||||
private void assignKeys(final StratNode<K> root) {
|
||||
int key = 0;
|
||||
for ( final StratNode<K> node : root ) {
|
||||
if ( node.isLeaf() )
|
||||
node.setKey(key++);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
//
|
||||
// simple accessors
|
||||
//
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
@Ensures("result >= 0")
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Ensures("result != null")
|
||||
public StratNode<K> getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
//
|
||||
// mapping from states -> keys
|
||||
//
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
@Requires("states != null")
|
||||
@Ensures("result >= -1")
|
||||
public int getKey(final List<Object> states) {
|
||||
return root.find(states, 0);
|
||||
}
|
||||
|
||||
@Requires("allStates != null")
|
||||
@Ensures("result != null")
|
||||
public Set<Integer> getKeys(final List<List<Object>> allStates) {
|
||||
final HashSet<Integer> keys = new HashSet<Integer>();
|
||||
root.find(allStates, 0, keys);
|
||||
return keys;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
//
|
||||
// values
|
||||
//
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
@Ensures("result != null")
|
||||
public ArrayList<V> 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<Object> states) {
|
||||
return get(getKey(states));
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(final Object o) {
|
||||
return get((List<Object>)o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsKey(final List<Object> o) {
|
||||
return getKey(o) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(final Object o) {
|
||||
return containsKey((List<Object>)o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(final Object o) {
|
||||
throw new ReviewedStingException("containsValue() not implemented for StratificationManager");
|
||||
}
|
||||
|
||||
@Override
|
||||
public V put(final List<Object> 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 List<Object>, ? 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<List<Object>> keySet() {
|
||||
throw new ReviewedStingException("Not yet implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<List<Object>, V>> entrySet() {
|
||||
throw new ReviewedStingException("Not yet implemented");
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
//
|
||||
// utilities
|
||||
//
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
public static List<List<Object>> combineStates(final List<Object> first, final List<Object> second) {
|
||||
List<List<Object>> combined = new ArrayList<List<Object>>(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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Integer> values() {
|
||||
final ArrayList<Integer> l = new ArrayList<Integer>();
|
||||
for ( int i = 0; i < nStates; i++ )
|
||||
l.add(i);
|
||||
return l;
|
||||
}
|
||||
|
||||
public Queue<List<Object>> getAllCombinations() {
|
||||
return getAllCombinations(new LinkedList<List<Object>>(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<ListAsSetOfStates, Integer> createManager(StratificationStatesTestProvider cfg) {
|
||||
final StratificationManager<ListAsSetOfStates, Integer> manager = new StratificationManager<ListAsSetOfStates, Integer>(cfg.getStateSpaceList());
|
||||
List<Integer> 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<ListAsSetOfStates> stratificationStates = new StratificationStates<ListAsSetOfStates>(cfg.getStateSpaceList());
|
||||
|
||||
Assert.assertEquals(stratificationStates.getNStates(), cfg.nStates);
|
||||
final StratificationManager<ListAsSetOfStates, Integer> 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<ListAsSetOfStates> stratificationStates = new StratificationStates<ListAsSetOfStates>(cfg.getStateSpaceList());
|
||||
final StratificationManager<ListAsSetOfStates, Integer> stratificationManager = createManager(cfg);
|
||||
final Set<Integer> seenKeys = new HashSet<Integer>(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<ListAsSetOfStates> stratificationStates = new StratificationStates<ListAsSetOfStates>(cfg.getStateSpaceList());
|
||||
final StratificationManager<ListAsSetOfStates, Integer> stratificationManager = createManager(cfg);
|
||||
final Set<Integer> seenKeys = new HashSet<Integer>(cfg.nStates);
|
||||
for ( List<Object> 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<ListAsSetOfStates> stratificationStates = new StratificationStates<ListAsSetOfStates>(cfg.getStateSpaceList());
|
||||
final StratificationManager<ListAsSetOfStates, Integer> stratificationManager = createManager(cfg);
|
||||
final List<List<Object>> states = new ArrayList<List<Object>>(cfg.allStates);
|
||||
final Set<Integer> keys = stratificationStates.getKeys(states);
|
||||
final Set<Integer> keys = stratificationManager.getKeys(states);
|
||||
Assert.assertEquals(keys.size(), cfg.nStates, "Find all states didn't find all of the expected unique keys");
|
||||
|
||||
final Queue<List<Object>> combinations = cfg.getAllCombinations();
|
||||
|
|
@ -186,12 +213,12 @@ public class StratificationStatesUnitTest extends BaseTest {
|
|||
List<Object> first = combinations.poll();
|
||||
List<Object> second = combinations.peek();
|
||||
if ( second != null ) {
|
||||
List<List<Object>> combined = StratificationStates.combineStates(first, second);
|
||||
List<List<Object>> combined = StratificationManager.combineStates(first, second);
|
||||
int nExpectedKeys = Utils.nCombinations(combined);
|
||||
|
||||
final int key1 = stratificationStates.getKey(first);
|
||||
final int key2 = stratificationStates.getKey(second);
|
||||
final Set<Integer> keysCombined = stratificationStates.getKeys(combined);
|
||||
final int key1 = stratificationManager.getKey(first);
|
||||
final int key2 = stratificationManager.getKey(second);
|
||||
final Set<Integer> 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<ListAsSetOfStates, Integer> stratificationManager = createManager(cfg);
|
||||
stratificationManager.set(0, -1);
|
||||
Assert.assertEquals((int)stratificationManager.get(0), -1);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue