From 260fa46a7806919137198ab41d1cea488113b42d Mon Sep 17 00:00:00 2001 From: Andrew Gerber Date: Wed, 7 Dec 2022 16:04:44 -0700 Subject: [PATCH 1/4] Begin developing custom MapOptionHandler --- .../imsam/args4j/MultiMapOptionHandler.java | 34 +++++++++ .../java/imsam/args4j/ParametersImpl.java | 50 +++++++++++++ .../args4j/MultiMapOptionHandlerTest.java | 70 +++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 src/main/java/imsam/args4j/MultiMapOptionHandler.java create mode 100644 src/main/java/imsam/args4j/ParametersImpl.java create mode 100644 src/test/java/imsam/args4j/MultiMapOptionHandlerTest.java diff --git a/src/main/java/imsam/args4j/MultiMapOptionHandler.java b/src/main/java/imsam/args4j/MultiMapOptionHandler.java new file mode 100644 index 0000000..80aec94 --- /dev/null +++ b/src/main/java/imsam/args4j/MultiMapOptionHandler.java @@ -0,0 +1,34 @@ +package imsam.args4j; + +import java.util.Map; + +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.OptionDef; +import org.kohsuke.args4j.spi.MapOptionHandler; +import org.kohsuke.args4j.spi.Parameters; +import org.kohsuke.args4j.spi.Setter; + +public class MultiMapOptionHandler extends MapOptionHandler { + + protected static final String delimiterRegex = ","; + + protected final CmdLineParser parser; + protected final OptionDef option; + + public MultiMapOptionHandler(CmdLineParser parser, OptionDef option, Setter> setter) { + super(parser, option, setter); + this.parser = parser; + this.option = option; + } + + @Override + public int parseArguments(Parameters params) throws CmdLineException { + for (String arg : params.getParameter(0).split(delimiterRegex)) { + Parameters splitParam = new ParametersImpl(new String[]{arg}, parser, option); + super.parseArguments(splitParam); + } + return 1; + } + +} diff --git a/src/main/java/imsam/args4j/ParametersImpl.java b/src/main/java/imsam/args4j/ParametersImpl.java new file mode 100644 index 0000000..41f1357 --- /dev/null +++ b/src/main/java/imsam/args4j/ParametersImpl.java @@ -0,0 +1,50 @@ +package imsam.args4j; + +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.OptionDef; +import org.kohsuke.args4j.spi.Parameters; + +public class ParametersImpl implements Parameters { + + private final CmdLineParser parser; + private final OptionDef option; + + private final String[] args; + private int pos; + + ParametersImpl(String[] args, CmdLineParser parser, OptionDef option) { + this.parser = parser; + this.option = option; + this.args = args; + pos = 0; + } + + @Override + @SuppressWarnings("deprecation") // Use CmdLineException without localization + public String getParameter(int idx) throws CmdLineException { + if (pos+idx >= args.length || pos+idx < 0) { + String msg = String.format("Option \"{0}\" takes an operand", option.toString()); + throw new CmdLineException(parser, msg); + } + return args[pos+idx]; + } + + @Override + public int size() { + return args.length - pos; + } + + public boolean hasMore() { + return pos < args.length; + } + + public String getCurrentToken() { + return args[pos]; + } + + public void proceed(int n) { + pos += n; + } + +} diff --git a/src/test/java/imsam/args4j/MultiMapOptionHandlerTest.java b/src/test/java/imsam/args4j/MultiMapOptionHandlerTest.java new file mode 100644 index 0000000..3075c04 --- /dev/null +++ b/src/test/java/imsam/args4j/MultiMapOptionHandlerTest.java @@ -0,0 +1,70 @@ +package imsam.args4j; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.Option; +import org.opentest4j.AssertionFailedError; + +public class MultiMapOptionHandlerTest { + + protected class TestClass { + @Option(name="--dict", metaVar="dict", handler=MultiMapOptionHandler.class) + public Map dictionary = new HashMap<>(); + } + + protected Map parse(String[] args) throws CmdLineException { + TestClass testClass = new TestClass<>(); + CmdLineParser parser = new CmdLineParser(testClass); + parser.parseArgument(args); + return testClass.dictionary; + } + + @Test + public void test_Empty() throws CmdLineException { + String[] args = {}; + Map map = parse(args); + assertTrue(map.isEmpty()); + } + + @Test + public void test_MapStringString() throws CmdLineException { + String[] args = "--dict foo=Hello --dict bar=World".split("\\s+"); + Map map = parse(args); + try { + assertEquals(2, map.size()); + assertEquals("Hello", map.get("foo")); + assertEquals("World", map.get("bar")); + } + catch (AssertionFailedError ex) { + System.err.println(map); + throw ex; + } + } + + @Test + public void test_MultiMap() throws CmdLineException { + String[] args = "--dict foo=99,bar=88,baz=77".split("\\s+"); + Map map = parse(args); + try { + assertEquals(3, map.size()); + assertEquals("99", map.get("foo")); + assertEquals("88", map.get("bar")); + assertEquals("77", map.get("baz")); + } + catch (AssertionFailedError ex) { + System.err.println("size="+map.size()); + map.forEach((key, value) -> { + System.err.println("'"+key+"' : '"+value+"'"); + }); + throw ex; + } + } + +} From 4ef28dba6292163e419460827e653881050ddd5b Mon Sep 17 00:00:00 2001 From: Andrew Gerber Date: Wed, 7 Dec 2022 17:30:42 -0700 Subject: [PATCH 2/4] Add Int and Double MapOptionHandlers --- src/main/java/imsam/Main.java | 15 +++---- .../imsam/args4j/MapDoubleOptionHandler.java | 21 +++++++++ .../imsam/args4j/MapIntOptionHandler.java | 21 +++++++++ .../args4j/Test_MapDoubleOptionHandler.java | 45 +++++++++++++++++++ .../args4j/Test_MapIntOptionHandler.java | 45 +++++++++++++++++++ ...t.java => Test_MultiMapOptionHandler.java} | 10 ++--- 6 files changed, 143 insertions(+), 14 deletions(-) create mode 100644 src/main/java/imsam/args4j/MapDoubleOptionHandler.java create mode 100644 src/main/java/imsam/args4j/MapIntOptionHandler.java create mode 100644 src/test/java/imsam/args4j/Test_MapDoubleOptionHandler.java create mode 100644 src/test/java/imsam/args4j/Test_MapIntOptionHandler.java rename src/test/java/imsam/args4j/{MultiMapOptionHandlerTest.java => Test_MultiMapOptionHandler.java} (87%) diff --git a/src/main/java/imsam/Main.java b/src/main/java/imsam/Main.java index e99fc4b..7b3c043 100644 --- a/src/main/java/imsam/Main.java +++ b/src/main/java/imsam/Main.java @@ -1,5 +1,7 @@ package imsam; +import java.util.stream.Stream; + import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -11,7 +13,6 @@ import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; -import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.SubCommand; import org.kohsuke.args4j.spi.SubCommandHandler; import org.kohsuke.args4j.spi.SubCommands; @@ -95,14 +96,10 @@ public static void printUsage(CmdLineException ex) { private static void _printUsage(CmdLineParser parser, boolean includeSubcommand) { System.err.println("Usage:"); System.err.print(" ./bin/run.sh"); - for (OptionHandler arg : Main.parser.getArguments()) { - System.err.print(" " + arg.getDefaultMetaVariable()); - } - if (includeSubcommand) { - for (OptionHandler arg : parser.getArguments()) { - System.err.print(" " + arg.getDefaultMetaVariable()); - } - } + Stream.concat( + Main.parser.getArguments().stream(), + parser.getArguments().stream() + ).forEachOrdered(opt -> System.err.print(" "+opt.getDefaultMetaVariable())); System.err.println(" [OPTIONS]...\n"); parser.printUsage(System.err); } diff --git a/src/main/java/imsam/args4j/MapDoubleOptionHandler.java b/src/main/java/imsam/args4j/MapDoubleOptionHandler.java new file mode 100644 index 0000000..5e8269b --- /dev/null +++ b/src/main/java/imsam/args4j/MapDoubleOptionHandler.java @@ -0,0 +1,21 @@ +package imsam.args4j; + +import java.util.Map; + +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.OptionDef; +import org.kohsuke.args4j.spi.Setter; + +public class MapDoubleOptionHandler extends MultiMapOptionHandler { + + public MapDoubleOptionHandler(CmdLineParser parser, OptionDef option, Setter> setter) { + super(parser, option, setter); + } + + @Override + @SuppressWarnings({"rawtypes", "unchecked"}) + protected void addToMap(Map m, String key, String value) { + m.put(key, Double.parseDouble(value)); + } + +} diff --git a/src/main/java/imsam/args4j/MapIntOptionHandler.java b/src/main/java/imsam/args4j/MapIntOptionHandler.java new file mode 100644 index 0000000..2fc25a1 --- /dev/null +++ b/src/main/java/imsam/args4j/MapIntOptionHandler.java @@ -0,0 +1,21 @@ +package imsam.args4j; + +import java.util.Map; + +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.OptionDef; +import org.kohsuke.args4j.spi.Setter; + +public class MapIntOptionHandler extends MultiMapOptionHandler { + + public MapIntOptionHandler(CmdLineParser parser, OptionDef option, Setter> setter) { + super(parser, option, setter); + } + + @Override + @SuppressWarnings({"rawtypes", "unchecked"}) + protected void addToMap(Map m, String key, String value) { + m.put(key, Integer.parseInt(value)); + } + +} diff --git a/src/test/java/imsam/args4j/Test_MapDoubleOptionHandler.java b/src/test/java/imsam/args4j/Test_MapDoubleOptionHandler.java new file mode 100644 index 0000000..f95c03a --- /dev/null +++ b/src/test/java/imsam/args4j/Test_MapDoubleOptionHandler.java @@ -0,0 +1,45 @@ +package imsam.args4j; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.Option; +import org.opentest4j.AssertionFailedError; + +public class Test_MapDoubleOptionHandler { + + protected class TestClass { + @Option(name="--dict", metaVar="dict", handler=MapDoubleOptionHandler.class) + public Map dictionary = new HashMap<>(); + } + + protected Map parse(String[] args) throws CmdLineException { + TestClass testClass = new TestClass(); + CmdLineParser parser = new CmdLineParser(testClass); + parser.parseArgument(args); + return testClass.dictionary; + } + + @Test + public void test_MapStringDouble() throws CmdLineException { + String[] args = "--dict foo=1.11 --dict bar=2.22 --dict baz=3.33".split("\\s+"); + Map map = parse(args); + try { + assertTrue(map.size() == 3); + assertEquals(1.11, map.get("foo")); + assertEquals(2.22, map.get("bar")); + assertEquals(3.33, map.get("baz")); + } + catch (AssertionFailedError ex) { + System.err.println(map); + throw ex; + } + } + +} diff --git a/src/test/java/imsam/args4j/Test_MapIntOptionHandler.java b/src/test/java/imsam/args4j/Test_MapIntOptionHandler.java new file mode 100644 index 0000000..b2c6ce7 --- /dev/null +++ b/src/test/java/imsam/args4j/Test_MapIntOptionHandler.java @@ -0,0 +1,45 @@ +package imsam.args4j; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.Option; +import org.opentest4j.AssertionFailedError; + +public class Test_MapIntOptionHandler { + + protected class TestClass { + @Option(name="--dict", metaVar="dict", handler=MapIntOptionHandler.class) + public Map dictionary = new HashMap<>(); + } + + protected Map parse(String[] args) throws CmdLineException { + TestClass testClass = new TestClass(); + CmdLineParser parser = new CmdLineParser(testClass); + parser.parseArgument(args); + return testClass.dictionary; + } + + @Test + public void test_MapStringInt() throws CmdLineException { + String[] args = "--dict foo=1 --dict bar=2 --dict baz=3".split("\\s+"); + Map map = parse(args); + try { + assertTrue(map.size() == 3); + assertEquals(1, map.get("foo")); + assertEquals(2, map.get("bar")); + assertEquals(3, map.get("baz")); + } + catch (AssertionFailedError ex) { + System.err.println(map); + throw ex; + } + } + +} diff --git a/src/test/java/imsam/args4j/MultiMapOptionHandlerTest.java b/src/test/java/imsam/args4j/Test_MultiMapOptionHandler.java similarity index 87% rename from src/test/java/imsam/args4j/MultiMapOptionHandlerTest.java rename to src/test/java/imsam/args4j/Test_MultiMapOptionHandler.java index 3075c04..68ca9da 100644 --- a/src/test/java/imsam/args4j/MultiMapOptionHandlerTest.java +++ b/src/test/java/imsam/args4j/Test_MultiMapOptionHandler.java @@ -12,15 +12,15 @@ import org.kohsuke.args4j.Option; import org.opentest4j.AssertionFailedError; -public class MultiMapOptionHandlerTest { +public class Test_MultiMapOptionHandler { - protected class TestClass { + protected class TestClass { @Option(name="--dict", metaVar="dict", handler=MultiMapOptionHandler.class) - public Map dictionary = new HashMap<>(); + public Map dictionary = new HashMap<>(); } - protected Map parse(String[] args) throws CmdLineException { - TestClass testClass = new TestClass<>(); + protected Map parse(String[] args) throws CmdLineException { + TestClass testClass = new TestClass(); CmdLineParser parser = new CmdLineParser(testClass); parser.parseArgument(args); return testClass.dictionary; From 8e2bf1598dc343a70bf7c4215afca0221fa4b8a7 Mon Sep 17 00:00:00 2001 From: Andrew Gerber Date: Wed, 7 Dec 2022 17:35:51 -0700 Subject: [PATCH 3/4] Add map of weights to arguments --- .../java/imsam/DynamicBinaryWeightedSSA.java | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/main/java/imsam/DynamicBinaryWeightedSSA.java b/src/main/java/imsam/DynamicBinaryWeightedSSA.java index d93f42c..7f13e54 100644 --- a/src/main/java/imsam/DynamicBinaryWeightedSSA.java +++ b/src/main/java/imsam/DynamicBinaryWeightedSSA.java @@ -15,29 +15,24 @@ package imsam; -import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; -import java.util.*;//ArrayList; -//import java.util.List; -//import java.util.Dictionary; -//import java.util.NoSuchElementException; -import java.lang.Math; +//ArrayList; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import org.apache.logging.log4j.Logger; import org.kohsuke.args4j.Option; -import parser.ast.ModulesFile; import parser.Values; - +import parser.ast.ModulesFile; +import prism.ModelGenerator; import prism.Prism; import prism.PrismDevNullLog; import prism.PrismException; import prism.PrismLog; -import prism.ModelGenerator; - import simulator.RandomNumberGenerator; import simulator.SimulatorEngine; @@ -74,8 +69,11 @@ public class DynamicBinaryWeightedSSA extends Command { @Option(name="--const",usage="Model constant name=value") public String modelConstant = ""; + @Option(name="--weight",usage="TODO: needs description") + public Map predilections = Map.of("[r3]", 1e20); + public String argsToString() { - return String.format("TMAX=%f Nruns=%d modelFile=%s ", TMAX, Nruns, modelFileName); + return String.format("TMAX=%f Nruns=%d modelFile=%s weights=%s", TMAX, Nruns, modelFileName, predilections); } public String argsRawToString() { return String.format("%f\t%d", TMAX, Nruns); @@ -90,10 +88,9 @@ public String argsRawToString() { public SimulatorEngine sim; public ModelGenerator info; - private int constraintIndex; - private int objectiveIndex; + //private int constraintIndex; + //private int objectiveIndex; private RandomNumberGenerator rng = new RandomNumberGenerator(); - private Dictionary predilections = new Hashtable(); @Override public int exec() throws IOException, PrismException { @@ -101,8 +98,6 @@ public int exec() throws IOException, PrismException { logger.debug("Running Dynamic Binary Weighted SSA"); loadModel(); - Double d=1e20; - predilections.put("[r3]",d); double sum = 0.0; long binarySum = 0; From a61358928fee6bd7f1353a4f1c6484b24a2a7288 Mon Sep 17 00:00:00 2001 From: Andrew Gerber Date: Wed, 7 Dec 2022 20:20:22 -0700 Subject: [PATCH 4/4] Use correct option handler in dbwSSA --- src/main/java/imsam/DynamicBinaryWeightedSSA.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/imsam/DynamicBinaryWeightedSSA.java b/src/main/java/imsam/DynamicBinaryWeightedSSA.java index 7f13e54..edea45a 100644 --- a/src/main/java/imsam/DynamicBinaryWeightedSSA.java +++ b/src/main/java/imsam/DynamicBinaryWeightedSSA.java @@ -26,6 +26,7 @@ import org.apache.logging.log4j.Logger; import org.kohsuke.args4j.Option; +import imsam.args4j.MapDoubleOptionHandler; import parser.Values; import parser.ast.ModulesFile; import prism.ModelGenerator; @@ -69,7 +70,7 @@ public class DynamicBinaryWeightedSSA extends Command { @Option(name="--const",usage="Model constant name=value") public String modelConstant = ""; - @Option(name="--weight",usage="TODO: needs description") + @Option(name="--weight",usage="TODO: needs description",handler=MapDoubleOptionHandler.class) public Map predilections = Map.of("[r3]", 1e20); public String argsToString() {