Approaching the end for the new RodBinding system

-- support for explicit naming of bindings (-X:name,type x)
-- support for automatic naming of bindings in lists (-X:vcf foo.vcf -X:vcf bar.vcf will generate internal names X and X2)
-- ParserEngineUnitTest expanded to cover all of the Rodbinding cases
-- RodBindingUnitTest tests all of the low-level accessors
-- Parsing engine throws UserExceptions when bad bindings are provided on the command line
This commit is contained in:
Mark DePristo 2011-08-02 22:00:06 -04:00
parent 83891271b5
commit b5e843f8f0
7 changed files with 355 additions and 45 deletions

View File

@ -312,10 +312,23 @@ class RodBindingArgumentTypeDescriptor extends ArgumentTypeDescriptor {
ArgumentDefinition defaultDefinition = createDefaultArgumentDefinition(source);
String value = getArgumentValue( defaultDefinition, matches );
try {
String name = source.field.getName();
String tribbleType;
Tags tags = getArgumentTags(matches);
Constructor ctor = (makeRawTypeIfNecessary(type)).getConstructor(Class.class, String.class, String.class, Tags.class);
// must have one or two tag values here
if ( tags.getPositionalTags().size() == 2 ) { // -X:name,type style
name = tags.getPositionalTags().get(0);
tribbleType = tags.getPositionalTags().get(1);
} else if ( tags.getPositionalTags().size() == 1 ) { // -X:type style
tribbleType = tags.getPositionalTags().get(0);
} else
throw new UserException.CommandLineException(
String.format("Unexpected number of positional tags for argument %s : %s. " +
"Rod bindings only suport -X:type and -X:name,type argument styles",
value, source.field.getName()));
Constructor ctor = (makeRawTypeIfNecessary(type)).getConstructor(Class.class, String.class, String.class, String.class, Tags.class);
Class parameterType = getParameterizedTypeClass(type);
RodBinding result = (RodBinding)ctor.newInstance(parameterType, source.field.getName(), value, tags);
RodBinding result = (RodBinding)ctor.newInstance(parameterType, name, value, tribbleType, tags);
parsingEngine.addTags(result,tags);
return result;
} catch (InvocationTargetException e) {

View File

@ -25,13 +25,8 @@
package org.broadinstitute.sting.commandline;
import org.broad.tribble.Feature;
import org.broadinstitute.sting.gatk.refdata.RefMetaDataTracker;
import org.broadinstitute.sting.gatk.refdata.utils.GATKFeature;
import org.broadinstitute.sting.utils.GenomeLoc;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.*;
/**
* A RodBinding representing a walker argument that gets bound to a ROD track.
@ -39,24 +34,46 @@ import java.util.List;
* There is no constraint on the type of the ROD bound.
*/
public class RodBinding<T extends Feature> {
protected final static String UNBOUND_VARIABLE_NAME = "";
protected final static String UNBOUND_SOURCE = "UNBOUND";
protected final static String UNBOUND_TRIBBLE_TYPE = null;
public final static <T extends Feature> RodBinding<T> makeUnbound(Class<T> type) {
return new RodBinding<T>(type);
}
final private String variableName;
final private String name;
final private String source;
final private String tribbleType;
final private Tags tags;
final private Class<T> type;
final private boolean bound;
final private static Map<String, Integer> nameCounter = new HashMap<String, Integer>();
final protected static void resetNameCounter() {
nameCounter.clear();
}
final private static synchronized String countedVariableName(final String rawName) {
Integer count = nameCounter.get(rawName);
if ( count == null ) {
nameCounter.put(rawName, 1);
return rawName;
} else {
nameCounter.put(rawName, count + 1);
return rawName + (count + 1);
}
}
public boolean isBound() {
return bound;
}
public RodBinding(Class<T> type, final String variableName, final String source, final Tags tags) {
public RodBinding(Class<T> type, final String rawName, final String source, final String tribbleType, final Tags tags) {
this.type = type;
this.variableName = variableName;
this.name = countedVariableName(rawName);
this.source = source;
this.tribbleType = tribbleType;
this.tags = tags;
this.bound = true;
}
@ -67,14 +84,15 @@ public class RodBinding<T extends Feature> {
*/
private RodBinding(Class<T> type) {
this.type = type;
this.variableName = ""; // special value can never be found in RefMetaDataTracker
this.source = "";
this.name = UNBOUND_VARIABLE_NAME; // special value can never be found in RefMetaDataTracker
this.source = UNBOUND_SOURCE;
this.tribbleType = UNBOUND_TRIBBLE_TYPE;
this.tags = new Tags();
this.bound = false;
}
public String getVariableName() {
return variableName;
public String getName() {
return name;
}
public Class<T> getType() {
return type;
@ -87,7 +105,11 @@ public class RodBinding<T extends Feature> {
return tags;
}
public String getTribbleType() {
return tribbleType;
}
public String toString() {
return String.format("(RodBinding name=%s source=%s)", getVariableName(), getSource());
return String.format("(RodBinding name=%s source=%s)", getName(), getSource());
}
}

View File

@ -6,11 +6,8 @@ import org.broadinstitute.sting.commandline.RodBinding;
import org.broadinstitute.sting.gatk.contexts.ReferenceContext;
import org.broadinstitute.sting.gatk.refdata.utils.GATKFeature;
import org.broadinstitute.sting.gatk.refdata.utils.RODRecordList;
import org.broadinstitute.sting.gatk.walkers.Reference;
import org.broadinstitute.sting.utils.GenomeLoc;
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
import org.broadinstitute.sting.utils.exceptions.UserException;
import org.broadinstitute.sting.utils.variantcontext.VariantContext;
import java.util.*;
@ -109,7 +106,7 @@ public class RefMetaDataTracker {
// ROD binding accessors
//
public <T extends Feature> List<T> getValues(final RodBinding<T> rodBinding) {
return getValues(rodBinding.getType(), rodBinding.getVariableName());
return getValues(rodBinding.getType(), rodBinding.getName());
}
public <T extends Feature> List<T> getValues(final Collection<RodBinding<T>> rodBindings) {
@ -120,7 +117,7 @@ public class RefMetaDataTracker {
}
public <T extends Feature> List<T> getValues(final RodBinding<T> rodBinding, final GenomeLoc onlyAtThisLoc) {
return getValues(rodBinding.getType(), rodBinding.getVariableName(), onlyAtThisLoc);
return getValues(rodBinding.getType(), rodBinding.getName(), onlyAtThisLoc);
}
public <T extends Feature> List<T> getValues(final Collection<RodBinding<T>> rodBindings, final GenomeLoc onlyAtThisLoc) {
@ -131,10 +128,10 @@ public class RefMetaDataTracker {
}
public <T extends Feature> T getFirstValue(final RodBinding<T> rodBinding) {
return getFirstValue(rodBinding.getType(), rodBinding.getVariableName());
return getFirstValue(rodBinding.getType(), rodBinding.getName());
}
public <T extends Feature> T getFirstValue(final RodBinding<T> rodBinding, final GenomeLoc onlyAtThisLoc) {
return getFirstValue(rodBinding.getType(), rodBinding.getVariableName(), onlyAtThisLoc);
return getFirstValue(rodBinding.getType(), rodBinding.getName(), onlyAtThisLoc);
}
public <T extends Feature> T getFirstValue(final Collection<RodBinding<T>> rodBindings) {
@ -158,11 +155,11 @@ public class RefMetaDataTracker {
public boolean hasValues(final RodBinding rodBinding) {
return hasValues(rodBinding.getVariableName());
return hasValues(rodBinding.getName());
}
public List<GATKFeature> getValuesAsGATKFeatures(final RodBinding rodBinding) {
return getValuesAsGATKFeatures(rodBinding.getVariableName());
return getValuesAsGATKFeatures(rodBinding.getName());
}
/**

View File

@ -28,7 +28,6 @@ import org.broadinstitute.sting.commandline.ParsingEngine;
import org.broadinstitute.sting.commandline.RodBinding;
import org.broadinstitute.sting.commandline.Tags;
import org.broadinstitute.sting.gatk.datasources.reads.SAMReaderID;
import org.broadinstitute.sting.gatk.refdata.features.DbSNPHelper;
import org.broadinstitute.sting.gatk.refdata.tracks.RMDTrackBuilder;
import org.broadinstitute.sting.gatk.refdata.utils.RMDTriplet;
import org.broadinstitute.sting.utils.exceptions.UserException;
@ -140,34 +139,25 @@ public class ListFileUtils {
for (RodBinding rodBinding: RODBindings) {
String argValue = rodBinding.getSource();
String fileName = expandFileName(argValue);
final Tags tags = parser.getTags(rodBinding);
List<String> positionalTags = tags.getPositionalTags();
if(positionalTags.size() != 1)
throw new UserException("Invalid syntax for RODBinding (reference-ordered data) input . " +
"Please use the following syntax when providing reference-ordered " +
"data: -<arg-name>:<type> <filename>.");
// Assume that if tags are present, those tags are name and type.
// Name is always first, followed by type.
String name = rodBinding.getVariableName();
String type = positionalTags.get(0);
String name = rodBinding.getName();
String type = rodBinding.getTribbleType();
RMDTriplet.RMDStorageType storageType = null;
if(tags.getValue("storage") != null)
storageType = Enum.valueOf(RMDTriplet.RMDStorageType.class,tags.getValue("storage"));
if(rodBinding.getTags().getValue("storage") != null)
storageType = Enum.valueOf(RMDTriplet.RMDStorageType.class,rodBinding.getTags().getValue("storage"));
else if(fileName.toLowerCase().endsWith("stdin"))
storageType = RMDTriplet.RMDStorageType.STREAM;
else
storageType = RMDTriplet.RMDStorageType.FILE;
RMDTriplet triplet = new RMDTriplet(name,type,fileName,storageType,tags);
RMDTriplet triplet = new RMDTriplet(name,type,fileName,storageType,rodBinding.getTags());
// validate triplet type
Class typeFromTribble = builderForValidation.getFeatureCodecClass(triplet);
if ( typeFromTribble != null && ! rodBinding.getType().isAssignableFrom(typeFromTribble) )
throw new UserException.BadArgumentValue(rodBinding.getVariableName(),
throw new UserException.BadArgumentValue(rodBinding.getName(),
String.format("Field %s expected type %s, but the type of the input file provided on the command line was %s",
rodBinding.getVariableName(), rodBinding.getType(), typeFromTribble));
rodBinding.getName(), rodBinding.getType(), typeFromTribble));
rodBindings.add(triplet);

View File

@ -25,12 +25,16 @@
package org.broadinstitute.sting.commandline;
import org.broad.tribble.Feature;
import org.broadinstitute.sting.utils.exceptions.UserException;
import org.broadinstitute.sting.utils.variantcontext.VariantContext;
import org.testng.Assert;
import org.broadinstitute.sting.BaseTest;
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import javax.script.Bindings;
import java.util.List;
import java.util.EnumSet;
/**
@ -42,6 +46,7 @@ public class ParsingEngineUnitTest extends BaseTest {
@BeforeMethod
public void setUp() {
parsingEngine = new ParsingEngine(null);
RodBinding.resetNameCounter();
}
private class InputFileArgProvider {
@ -62,7 +67,7 @@ public class ParsingEngineUnitTest extends BaseTest {
Assert.assertEquals(argProvider.inputFile,"na12878.bam","Argument is not correctly initialized");
}
@Test
public void multiCharShortNameArgumentTest() {
final String[] commandLine = new String[] {"-out","out.txt"};
@ -211,7 +216,7 @@ public class ParsingEngineUnitTest extends BaseTest {
Assert.assertEquals(argProvider.testEnum, TestEnum.ONE, "Enum value is not correct");
}
@Test
public void enumDefaultTest() {
final String[] commandLine = new String[] {};
@ -552,7 +557,7 @@ public class ParsingEngineUnitTest extends BaseTest {
commandLine = new String[] {"--foo","5","--bar","6"};
parsingEngine.parse( commandLine );
parsingEngine.validate();
parsingEngine.validate();
}
private class MutuallyExclusiveArgProvider {
@ -618,4 +623,179 @@ public class ParsingEngineUnitTest extends BaseTest {
@ArgumentCollection
RequiredArgProvider rap2 = new RequiredArgProvider();
}
// --------------------------------------------------------------------------------
//
// Tests of the RodBinding<T> system
//
// --------------------------------------------------------------------------------
private class SingleRodBindingArgProvider {
@Input(shortName="V", required=false)
public RodBinding<Feature> binding = RodBinding.makeUnbound(Feature.class);
}
@Test
public void basicRodBindingArgumentTest() {
final String[] commandLine = new String[] {"-V:vcf","foo.vcf"};
parsingEngine.addArgumentSource( SingleRodBindingArgProvider.class );
parsingEngine.parse( commandLine );
parsingEngine.validate();
SingleRodBindingArgProvider argProvider = new SingleRodBindingArgProvider();
parsingEngine.loadArgumentsIntoObject( argProvider );
Assert.assertEquals(argProvider.binding.getName(), "binding", "Name isn't set properly");
Assert.assertEquals(argProvider.binding.getSource(), "foo.vcf", "Source isn't set to its expected value");
Assert.assertEquals(argProvider.binding.getType(), Feature.class, "Type isn't set to its expected value");
Assert.assertEquals(argProvider.binding.isBound(), true, "Bound() isn't returning its expected value");
Assert.assertEquals(argProvider.binding.getTags().getPositionalTags().size(), 1, "Tags aren't correctly set");
}
@Test
public void unbasicRodBindingArgumentTest() {
final String[] commandLine = new String[] {};
parsingEngine.addArgumentSource( SingleRodBindingArgProvider.class );
parsingEngine.parse( commandLine );
parsingEngine.validate();
SingleRodBindingArgProvider argProvider = new SingleRodBindingArgProvider();
parsingEngine.loadArgumentsIntoObject( argProvider );
Assert.assertEquals(argProvider.binding.getName(), RodBinding.UNBOUND_VARIABLE_NAME, "Name isn't set properly");
Assert.assertEquals(argProvider.binding.getSource(), RodBinding.UNBOUND_SOURCE, "Source isn't set to its expected value");
Assert.assertEquals(argProvider.binding.getType(), Feature.class, "Type isn't set to its expected value");
Assert.assertEquals(argProvider.binding.isBound(), false, "Bound() isn't returning its expected value");
Assert.assertEquals(argProvider.binding.getTags().getPositionalTags().size(), 0, "Tags aren't correctly set");
}
@Test(expectedExceptions = UserException.class)
public void rodBindingArgumentTestMissingType() {
final String[] commandLine = new String[] {"-V","foo.vcf"};
parsingEngine.addArgumentSource( SingleRodBindingArgProvider.class );
parsingEngine.parse( commandLine );
parsingEngine.validate();
SingleRodBindingArgProvider argProvider = new SingleRodBindingArgProvider();
parsingEngine.loadArgumentsIntoObject(argProvider);
}
@Test(expectedExceptions = UserException.class)
public void rodBindingArgumentTestTooManyTags() {
final String[] commandLine = new String[] {"-V:x,y,z","foo.vcf"};
parsingEngine.addArgumentSource( SingleRodBindingArgProvider.class );
parsingEngine.parse( commandLine );
parsingEngine.validate();
SingleRodBindingArgProvider argProvider = new SingleRodBindingArgProvider();
parsingEngine.loadArgumentsIntoObject(argProvider);
}
private class VariantContextRodBindingArgProvider {
@Input(shortName="V")
public RodBinding<VariantContext> binding;
}
@Test
public void variantContextBindingArgumentTest() {
final String[] commandLine = new String[] {"-V:vcf","foo.vcf"};
parsingEngine.addArgumentSource( VariantContextRodBindingArgProvider.class );
parsingEngine.parse( commandLine );
parsingEngine.validate();
VariantContextRodBindingArgProvider argProvider = new VariantContextRodBindingArgProvider();
parsingEngine.loadArgumentsIntoObject( argProvider );
Assert.assertEquals(argProvider.binding.getName(), "binding", "Name isn't set properly");
Assert.assertEquals(argProvider.binding.getSource(), "foo.vcf", "Source isn't set to its expected value");
Assert.assertEquals(argProvider.binding.getType(), VariantContext.class, "Type isn't set to its expected value");
Assert.assertEquals(argProvider.binding.getTags().getPositionalTags().size(), 1, "Tags aren't correctly set");
}
private class ListRodBindingArgProvider {
@Input(shortName="V", required=false)
public List<RodBinding<Feature>> bindings;
}
@Test
public void listRodBindingArgumentTest() {
final String[] commandLine = new String[] {"-V:vcf","foo.vcf"};
parsingEngine.addArgumentSource( ListRodBindingArgProvider.class );
parsingEngine.parse( commandLine );
parsingEngine.validate();
ListRodBindingArgProvider argProvider = new ListRodBindingArgProvider();
parsingEngine.loadArgumentsIntoObject( argProvider );
Assert.assertEquals(argProvider.bindings.size(), 1, "Unexpected number of bindings");
RodBinding<Feature> binding = argProvider.bindings.get(0);
Assert.assertEquals(binding.getName(), "bindings", "Name isn't set properly");
Assert.assertEquals(binding.getSource(), "foo.vcf", "Source isn't set to its expected value");
Assert.assertEquals(binding.getType(), Feature.class, "Type isn't set to its expected value");
Assert.assertEquals(binding.getTags().getPositionalTags().size(), 1, "Tags aren't correctly set");
}
@Test
public void listRodBindingArgumentTest2Args() {
final String[] commandLine = new String[] {"-V:vcf","foo.vcf", "-V:vcf", "bar.vcf"};
parsingEngine.addArgumentSource( ListRodBindingArgProvider.class );
parsingEngine.parse( commandLine );
parsingEngine.validate();
ListRodBindingArgProvider argProvider = new ListRodBindingArgProvider();
parsingEngine.loadArgumentsIntoObject( argProvider );
Assert.assertEquals(argProvider.bindings.size(), 2, "Unexpected number of bindings");
RodBinding<Feature> binding = argProvider.bindings.get(0);
Assert.assertEquals(binding.getName(), "bindings", "Name isn't set properly");
Assert.assertEquals(binding.getSource(), "foo.vcf", "Source isn't set to its expected value");
Assert.assertEquals(binding.getType(), Feature.class, "Type isn't set to its expected value");
Assert.assertEquals(binding.getTags().getPositionalTags().size(), 1, "Tags aren't correctly set");
RodBinding<Feature> binding2 = argProvider.bindings.get(1);
Assert.assertEquals(binding2.getName(), "bindings2", "Name isn't set properly");
Assert.assertEquals(binding2.getSource(), "bar.vcf", "Source isn't set to its expected value");
Assert.assertEquals(binding2.getType(), Feature.class, "Type isn't set to its expected value");
Assert.assertEquals(binding2.getTags().getPositionalTags().size(), 1, "Tags aren't correctly set");
}
@Test
public void listRodBindingArgumentTest0Args() {
final String[] commandLine = new String[] {};
parsingEngine.addArgumentSource( ListRodBindingArgProvider.class );
parsingEngine.parse( commandLine );
parsingEngine.validate();
ListRodBindingArgProvider argProvider = new ListRodBindingArgProvider();
parsingEngine.loadArgumentsIntoObject( argProvider );
Assert.assertNull(argProvider.bindings, "Bindings were not null");
}
@Test
public void listRodBindingArgumentTestExplicitlyNamed() {
final String[] commandLine = new String[] {"-V:foo,vcf","foo.vcf", "-V:foo,vcf", "bar.vcf"};
parsingEngine.addArgumentSource( ListRodBindingArgProvider.class );
parsingEngine.parse( commandLine );
parsingEngine.validate();
ListRodBindingArgProvider argProvider = new ListRodBindingArgProvider();
parsingEngine.loadArgumentsIntoObject( argProvider );
Assert.assertEquals(argProvider.bindings.size(), 2, "Unexpected number of bindings");
Assert.assertEquals(argProvider.bindings.get(0).getName(), "foo", "Name isn't set properly");
Assert.assertEquals(argProvider.bindings.get(1).getName(), "foo2", "Name isn't set properly");
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2011, 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.commandline;
import org.broadinstitute.sting.BaseTest;
import org.broadinstitute.sting.utils.variantcontext.VariantContext;
import org.testng.Assert;
import org.testng.annotations.Test;
/**
* Test suite for the parsing engine.
*/
public class RodBindingUnitTest extends BaseTest {
Tags mytags = new Tags();
@Test
public void testStandardRodBinding() {
RodBinding<VariantContext> b = new RodBinding<VariantContext>(VariantContext.class, "b", "foo", "vcf", mytags);
Assert.assertEquals(b.getName(), "b");
Assert.assertEquals(b.getType(), VariantContext.class);
Assert.assertEquals(b.getSource(), "foo");
Assert.assertEquals(b.getTribbleType(), "vcf");
Assert.assertEquals(b.isBound(), true);
}
@Test
public void testUnboundRodBinding() {
RodBinding<VariantContext> u = RodBinding.makeUnbound(VariantContext.class);
Assert.assertEquals(u.getName(), RodBinding.UNBOUND_VARIABLE_NAME);
Assert.assertEquals(u.getSource(), RodBinding.UNBOUND_SOURCE);
Assert.assertEquals(u.getType(), VariantContext.class);
Assert.assertEquals(u.getTribbleType(), RodBinding.UNBOUND_TRIBBLE_TYPE);
Assert.assertEquals(u.isBound(), false);
}
@Test
public void testMultipleBindings() {
String name = "binding";
RodBinding<VariantContext> b1 = new RodBinding<VariantContext>(VariantContext.class, name, "foo", "vcf", mytags);
Assert.assertEquals(b1.getName(), name);
Assert.assertEquals(b1.getType(), VariantContext.class);
Assert.assertEquals(b1.getSource(), "foo");
Assert.assertEquals(b1.getTribbleType(), "vcf");
Assert.assertEquals(b1.isBound(), true);
RodBinding<VariantContext> b2 = new RodBinding<VariantContext>(VariantContext.class, name, "foo", "vcf", mytags);
Assert.assertEquals(b2.getName(), name + "2");
Assert.assertEquals(b2.getType(), VariantContext.class);
Assert.assertEquals(b2.getSource(), "foo");
Assert.assertEquals(b2.getTribbleType(), "vcf");
Assert.assertEquals(b2.isBound(), true);
}
}

View File

@ -24,10 +24,20 @@
package org.broadinstitute.sting.gatk;
import org.broad.tribble.Feature;
import org.broadinstitute.sting.WalkerTest;
import org.broadinstitute.sting.commandline.Input;
import org.broadinstitute.sting.commandline.RodBinding;
import org.broadinstitute.sting.gatk.contexts.AlignmentContext;
import org.broadinstitute.sting.gatk.contexts.ReferenceContext;
import org.broadinstitute.sting.gatk.refdata.RefMetaDataTracker;
import org.broadinstitute.sting.gatk.walkers.RodWalker;
import org.broadinstitute.sting.utils.exceptions.UserException;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.List;
/**
*
*/
@ -56,3 +66,26 @@ public class EngineFeaturesIntegrationTest extends WalkerTest {
testBadRODBindingInput("bedXXX", "Unknown input to VCF expecting walker");
}
}
//class TestRodBindings extends RodWalker<Integer, Integer> {
// @Input(fullName="req", required=true)
// public RodBinding<Feature> required;
//
// @Input(fullName="optional", required=false)
// public RodBinding<Feature> optional = RodBinding.makeUnbound(Feature.class);
//
// @Input(fullName="rodList", shortName="RL", doc="A list of ROD types that we will convert to a table", required=true)
// public List<RodBinding<Feature>> variantsList;
//
// public void initialize() {
// // bound values
// Assert.assertEquals(required.isBound(), true);
//
//
// System.exit(0);
// }
//
// public Integer map(RefMetaDataTracker tracker, ReferenceContext ref, AlignmentContext context) { return 0; }
// public Integer reduceInit() { return 0; }
// public Integer reduce(Integer counter, Integer sum) { return counter + sum; }
//}