diff --git a/.github/workflows/SimPathsBuild.yml b/.github/workflows/SimPathsBuild.yml index fd2acf1..17e81e1 100644 --- a/.github/workflows/SimPathsBuild.yml +++ b/.github/workflows/SimPathsBuild.yml @@ -53,7 +53,13 @@ jobs: path: . - name: Setup run - run: java -jar singlerun.jar -c UK -s 2017 -Setup -g false + run: java -jar singlerun.jar -c UK -s 2017 -Setup -g false --rewrite-policy-schedule + + - name: Check input db exists + id: check_file + uses: thebinaryfelix/check-file-existence-action@1.0.0 + with: + files: 'input/input.mv.db, input/EUROMODpolicySchedule.xlsx, input/DatabaseCountryYear.xlsx' - name: Do one run run: java -jar multirun.jar -p 20000 -s 2017 -e 2020 -r 100 -n 2 -g false \ No newline at end of file diff --git a/README.md b/README.md index fe989dd..175a2bc 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ To run the SimPathsStart setup phases and set up a population for subsequent mul - `-c` Country ['UK' or 'IT'] - `-s` Start year - `-g` [true/false] show/hide gui +- `-r` Re-write policy schedule from detected policy files - `-Setup` do setup phases (creating input populations database) only e.g. @@ -70,13 +71,15 @@ For multiple runs, `multirun.jar` takes the following options: - `-s` start year of runs - `-e` end year of runs - `-g` [true/false] show/hide gui -- `-f` write console output to file (in 'output/logs/run_[seed].txt') +- `-f` write console output and logs to file (in 'output/logs/run_[seed].txt') e.g. ``` $ java -jar multirun.jar -r 100 -p 50000 -n 20 -s 2017 -e 2020 -g false -f ``` +Run `java -jar singlerun.jar -h` or `java -jar multirun.jar -h` to show these help messages. + ### Contributing 1. Create a new branch for your contributions. This will likely be based on either the `main` branch of this repository (if you seek to modify the stable version of the model) or `develop` (if you seek to modify the most recent version of the model). Please see branch naming convention below. diff --git a/src/main/java/simpaths/data/Parameters.java b/src/main/java/simpaths/data/Parameters.java index 0174ee3..4bb723c 100644 --- a/src/main/java/simpaths/data/Parameters.java +++ b/src/main/java/simpaths/data/Parameters.java @@ -1795,7 +1795,9 @@ public static TreeMap calculateEUROMODpolicySchedule(Country co MultiKey k = (MultiKey)o; if(k.getKey(0) != null) { String name = k.getKey(0).toString(); - if(name != null) { + if(name != null && + currentEUROMODpolicySchedule.getValue(name, EUROMODpolicyScheduleHeadingScenarioYearBegins) != null && + currentEUROMODpolicySchedule.getValue(name, EUROMODpolicyScheduleHeadingScenarioSystemYear) != null) { String policyStartYearString = currentEUROMODpolicySchedule.getValue(name, EUROMODpolicyScheduleHeadingScenarioYearBegins).toString(); String policySystemYearString = currentEUROMODpolicySchedule.getValue(name, EUROMODpolicyScheduleHeadingScenarioSystemYear).toString(); if(policyStartYearString != null && !policyStartYearString.isEmpty()) { diff --git a/src/main/java/simpaths/experiment/SimPathsMultiRun.java b/src/main/java/simpaths/experiment/SimPathsMultiRun.java index 0583c9e..5b2e21c 100644 --- a/src/main/java/simpaths/experiment/SimPathsMultiRun.java +++ b/src/main/java/simpaths/experiment/SimPathsMultiRun.java @@ -190,7 +190,7 @@ private static boolean parseCommandLineArgs(String[] args) { } catch (ParseException e) { System.err.println("Error parsing command line arguments: " + e.getMessage()); formatter.printHelp("SimPathsMultiRun", options); - System.exit(1); + return false; } return true; diff --git a/src/main/java/simpaths/experiment/SimPathsStart.java b/src/main/java/simpaths/experiment/SimPathsStart.java index e472e86..be9a128 100644 --- a/src/main/java/simpaths/experiment/SimPathsStart.java +++ b/src/main/java/simpaths/experiment/SimPathsStart.java @@ -5,10 +5,7 @@ import java.awt.Dimension; import org.apache.commons.cli.*; import java.awt.Toolkit; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; @@ -67,6 +64,8 @@ public class SimPathsStart implements ExperimentBuilder { private static boolean setupOnly = false; + private static boolean rewritePolicySchedule = false; + /** * @@ -85,7 +84,12 @@ public static void main(String[] args) { // display dialog box to allow users to define desired simulation runGUIdialog(); } else { - runGUIlessSetup(4); + try { + runGUIlessSetup(4); + } catch (FileNotFoundException f) { + System.err.println(f.getMessage()); + System.exit(1); + }; } if (setupOnly) { @@ -130,6 +134,9 @@ private static boolean parseCommandLineArgs(String[] args) { Option setupOption = new Option("Setup", "Setup only"); options.addOption(setupOption); + Option rewritePolicyScheduleOption = new Option("r", "rewrite-policy-schedule",false, "Re-write policy schedule from detected policy files"); + options.addOption(rewritePolicyScheduleOption); + Option guiOption = new Option("g", "showGui", true, "Show GUI"); guiOption.setArgName("true/false"); options.addOption(guiOption); @@ -154,7 +161,11 @@ private static boolean parseCommandLineArgs(String[] args) { } if (cmd.hasOption("c")) { - country = Country.valueOf(cmd.getOptionValue("c")); + try { + country = Country.valueOf(cmd.getOptionValue("c")); + } catch (Exception e) { + throw new IllegalArgumentException("Code '" + cmd.getOptionValue("c") + "' not a valid country."); + } } if (cmd.hasOption("s")) { @@ -164,10 +175,14 @@ private static boolean parseCommandLineArgs(String[] args) { if (cmd.hasOption("Setup")) { setupOnly = true; } + + if (cmd.hasOption("r")) { + rewritePolicySchedule = true; + } } catch (ParseException | IllegalArgumentException e) { System.err.println("Error parsing command line arguments: " + e.getMessage()); formatter.printHelp("SimPathsStart", options); - System.exit(1); + return false; } return true; @@ -205,7 +220,7 @@ public void buildExperiment(SimulationEngine engine) { model.setCollector(collector); } - private static void runGUIlessSetup(int option) { + private static void runGUIlessSetup(int option) throws FileNotFoundException { // Detect if data available; set to testing data if not Collection testList = FileUtils.listFiles(new File(Parameters.getInputDirectoryInitialPopulations()), new String[]{"csv"}, false); @@ -217,7 +232,13 @@ private static void runGUIlessSetup(int option) { Parameters.setTaxDonorInputFileName(taxDonorInputFilename); // Create EUROMODPolicySchedule input from files - writePolicyScheduleExcelFile(); + if (!rewritePolicySchedule && + !new File("input" + File.separator + Parameters.EUROMODpolicyScheduleFilename + ".xlsx").exists()) { + throw new FileNotFoundException("Policy Schedule file '"+ File.separator + "input" + File.separator + + Parameters.EUROMODpolicyScheduleFilename + ".xlsx` doesn't exist. " + + "Provide excel file or use `--rewrite-policy-schedule` to re-construct from available policy files."); + }; + if (rewritePolicySchedule) writePolicyScheduleExcelFile(); //Save the last selected country and year to Excel to use in the model if GUI launched straight away String[] columnNames = {"Country", "Year"}; Object[][] data = new Object[1][columnNames.length]; diff --git a/src/test/java/simpaths/experiment/SimPathsStartTest.java b/src/test/java/simpaths/experiment/SimPathsStartTest.java index 87b494b..9021c69 100644 --- a/src/test/java/simpaths/experiment/SimPathsStartTest.java +++ b/src/test/java/simpaths/experiment/SimPathsStartTest.java @@ -22,7 +22,7 @@ public static void setUpStreams() { @BeforeEach public void resetStreams() { outContent.reset(); -// errContent.reset(); + errContent.reset(); } @Test @@ -47,5 +47,13 @@ public void testSimPathsStartHelpOptionWithOtherArguments() { assertEquals("", errContent.toString().trim()); } - // Add more test methods for other scenarios as needed + @Test + public void testBadCountryName() { + String[] args = {"-g", "false", "-s", "2017", "-c", "XX"}; + + String expectedError = "Code 'XX' not a valid country."; + + SimPathsStart.main(args); + assertTrue(errContent.toString().contains(expectedError)); + } }