Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
974c191
de-finalise input directory and input filenames
andrewbaxter439 Nov 21, 2024
8d82eef
getters and setters for amendable input dirs
andrewbaxter439 Nov 21, 2024
0204764
replace all mentions in Parameters.java of input with input dir getter
andrewbaxter439 Nov 21, 2024
bfeae9c
de-finalise some potential changing parameters
andrewbaxter439 Nov 21, 2024
d31cef7
simpaths start calls dynamic input folder loc
andrewbaxter439 Nov 21, 2024
641f407
reads in parameter args
andrewbaxter439 Nov 21, 2024
55926f2
setting paramters including input directory in Experiment
andrewbaxter439 Nov 21, 2024
c42085d
update parameters (when building model)
andrewbaxter439 Nov 21, 2024
166e4b6
experimental configs
andrewbaxter439 Nov 21, 2024
7cdf68b
add logging
andrewbaxter439 Nov 21, 2024
66dec30
correct file finding
andrewbaxter439 Nov 21, 2024
78855ae
parse input folder before looking up country
andrewbaxter439 Nov 21, 2024
8963b4a
Merge remote-tracking branch 'sphsu-origin/develop' into experimental…
andrewbaxter439 Nov 26, 2024
3ab6723
Merge branch 'develop' into experimental/73-selecting-specific-input-…
andrewbaxter439 Jun 23, 2025
bcfabdd
some safe checking for last database country file if doesnt exist
andrewbaxter439 Jun 23, 2025
008221a
correct persist root database ref
andrewbaxter439 Jun 23, 2025
c173ef8
correct database parsing path
andrewbaxter439 Jun 23, 2025
6043d3e
override all calls to static root database in parameters
andrewbaxter439 Jun 23, 2025
cde7ba7
detect if input filder is absolute or not
andrewbaxter439 Jun 23, 2025
5bb70b7
prefer lower-case args to parameters
andrewbaxter439 Jun 23, 2025
2fc7419
fixes to find correct input folder (maybe?)
andrewbaxter439 Jun 23, 2025
f25063c
eq5d test file moved to test folder
andrewbaxter439 Jun 23, 2025
f377ed7
caught one last reference to static root database
andrewbaxter439 Jun 23, 2025
c64aa5b
change yaml file to commented out defaults
andrewbaxter439 Jun 23, 2025
e8d9e5d
ensure parsing of aboslute/relative paths in pop/euromod args
andrewbaxter439 Jun 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,9 @@ collector_args:
# persistBenefitUnits: false
# persistHouseholds: false
# dataDumpStartTime: 0L
# dataDumpTimePeriod: 1.0
# dataDumpTimePeriod: 1.0

parameter_args:
# input_directory: input
# input_directory_initial_populations: input/InitialPopulations
# euromod_output_directory: input/EUROMODoutput
425 changes: 233 additions & 192 deletions src/main/java/simpaths/data/Parameters.java

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/main/java/simpaths/data/startingpop/DataParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ public static void databaseFromCSV(Country country, boolean showGui) {
Connection conn = null;
try {
Class.forName("org.h2.Driver");
conn = DriverManager.getConnection("jdbc:h2:file:./input" + File.separator + "input;TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=0;AUTO_SERVER=TRUE", "sa", "");
conn = DriverManager.getConnection("jdbc:h2:file:" + Parameters.getInputDirectory() + "input;TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=0;AUTO_SERVER=TRUE", "sa", "");
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing file separator when building the H2 JDBC URL; add File.separator between the configured directory and input.

Suggested change
conn = DriverManager.getConnection("jdbc:h2:file:" + Parameters.getInputDirectory() + "input;TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=0;AUTO_SERVER=TRUE", "sa", "");
conn = DriverManager.getConnection("jdbc:h2:file:" + java.nio.file.Paths.get(Parameters.getInputDirectory(), "input").toString() + ";TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=0;AUTO_SERVER=TRUE", "sa", "");

Copilot uses AI. Check for mistakes.

Parameters.setPopulationInitialisationInputFileName("population_initial_" + country.toString());

Expand Down
71 changes: 61 additions & 10 deletions src/main/java/simpaths/experiment/SimPathsMultiRun.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import simpaths.data.Parameters;
import simpaths.data.XLSXfileWriter;
import simpaths.model.SimPathsModel;
import microsim.data.db.Experiment;
import microsim.data.MultiKeyCoefficientMap;
import microsim.data.excel.ExcelAssistant;
import microsim.engine.MultiRun;
Expand Down Expand Up @@ -73,21 +74,26 @@ public static void main(String[] args) {
// if parseYamlConfig returns false (indicating bad filename passed), exit main
return;
}

if (parameterArgs != null)
updateParameters(parameterArgs);


// set default values for country and start year
MultiKeyCoefficientMap lastDatabaseCountryAndYear = ExcelAssistant.loadCoefficientMap("input" + File.separator + Parameters.DatabaseCountryYearFilename + ".xlsx", "Data", 1, 1);
if (lastDatabaseCountryAndYear.keySet().stream().anyMatch(key -> key.toString().equals("MultiKey[IT]"))) {
countryString = "Italy";
} else {
MultiKeyCoefficientMap lastDatabaseCountryAndYear = ExcelAssistant.loadCoefficientMap(Parameters.getInputDirectory() + File.separator + Parameters.DatabaseCountryYearFilename + ".xlsx", "Data", 1, 1);
try {
if (lastDatabaseCountryAndYear.keySet().stream().anyMatch(key -> key.toString().equals("MultiKey[IT]"))) {
countryString = "Italy";
} else {
countryString = "United Kingdom";
}
String valueYear = lastDatabaseCountryAndYear.getValue(country.toString()).toString();
startYear = Integer.parseInt(valueYear);
} catch (NullPointerException e) {
System.out.println("No last database country and year found.");
countryString = "United Kingdom";
startYear = 2019;
}

country = Country.getCountryFromNameString(countryString);
String valueYear = lastDatabaseCountryAndYear.getValue(country.toString()).toString();
startYear = Integer.parseInt(valueYear);

if (innovationArgs!=null)
updateLocalParameters(innovationArgs);
Expand Down Expand Up @@ -402,6 +408,20 @@ public static void updateParameters(Map<String, Object> parameter_args) {
Object value = entry.getValue();

switch (key) {
case "working_directory":
Parameters.setWorkingDirectory(value.toString());
setExperimentFolders(value.toString(), true);
break;
case "input_directory":
Parameters.setInputDirectory(value.toString());
setExperimentFolders();
break;
case "input_directory_initial_populations":
Parameters.setInputDirectoryInitialPopulations(value.toString());
break;
case "euromod_output_directory":
Parameters.setEuromodOutputDirectory(value.toString());
break;
default:
try {
Field field = Parameters.class.getDeclaredField(key);
Expand All @@ -428,6 +448,37 @@ public static void updateParameters(Map<String, Object> parameter_args) {

}

public static void setExperimentFolders() {

try {
Field inputDir = Experiment.class.getDeclaredField("inputFolder");
inputDir.setAccessible(true);
inputDir.set(Experiment.class, Parameters.getInputDirectory());
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For setting a static field via reflection, the first argument to Field.set should be null, not Experiment.class. Use inputDir.set(null, Parameters.getInputDirectory()).

Suggested change
inputDir.set(Experiment.class, Parameters.getInputDirectory());
inputDir.set(null, Parameters.getInputDirectory());

Copilot uses AI. Check for mistakes.
inputDir.setAccessible(false);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}

}
public static void setExperimentFolders(String root_dir, boolean working_dir) {

try {
Field inputDir = Experiment.class.getDeclaredField("inputFolder");
inputDir.setAccessible(true);
inputDir.set(null, root_dir + File.separator + "input");
inputDir.setAccessible(false);
if (working_dir) {
Field outputDir = Experiment.class.getDeclaredField("outputRootFolder");
outputDir.setAccessible(true);
outputDir.set(null, root_dir + File.separator + "output");
outputDir.setAccessible(false);
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}

}

private static Object convertToType(Object value, Class<?> targetType) {
// Convert the YAML value to the target type
if (int.class.equals(targetType)) {
Expand All @@ -453,7 +504,7 @@ public void buildExperiment(SimulationEngine engine) {

SimPathsModel model = new SimPathsModel(Country.getCountryFromNameString(countryString), startYear);
if (persist_population) model.setPersistPopulation(true);
if (persist_root) model.setPersistDatabasePath("./input/input");
if (persist_root) model.setPersistDatabasePath(Parameters.getInputDirectory() + "input");
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concatenation lacks a separator before input; include File.separator (or ensure the directory string ends with one) to avoid malformed paths.

Suggested change
if (persist_root) model.setPersistDatabasePath(Parameters.getInputDirectory() + "input");
if (persist_root) model.setPersistDatabasePath(ensureTrailingSeparator(Parameters.getInputDirectory()) + "input");

Copilot uses AI. Check for mistakes.
updateLocalParameters(model);
if (modelArgs != null)
updateParameters(model, modelArgs);
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/simpaths/experiment/SimPathsStart.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public static void main(String[] args) {
}

//Adjust the country and year to the value read from Excel, which is updated when the database is rebuilt. Otherwise it will set the country and year to the last one used to build the database
MultiKeyCoefficientMap lastDatabaseCountryAndYear = ExcelAssistant.loadCoefficientMap("input" + File.separator + Parameters.DatabaseCountryYearFilename + ".xlsx", "Data", 1, 1);
MultiKeyCoefficientMap lastDatabaseCountryAndYear = ExcelAssistant.loadCoefficientMap(Parameters.getInputDirectory() + Parameters.DatabaseCountryYearFilename + ".xlsx", "Data", 1, 1);
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concatenating getInputDirectory() and filename without a separator may cause missing-path errors; consider adding File.separator between them.

Suggested change
MultiKeyCoefficientMap lastDatabaseCountryAndYear = ExcelAssistant.loadCoefficientMap(Parameters.getInputDirectory() + Parameters.DatabaseCountryYearFilename + ".xlsx", "Data", 1, 1);
MultiKeyCoefficientMap lastDatabaseCountryAndYear = ExcelAssistant.loadCoefficientMap(
java.nio.file.Paths.get(Parameters.getInputDirectory(), Parameters.DatabaseCountryYearFilename + ".xlsx").toString(),
"Data", 1, 1);

Copilot uses AI. Check for mistakes.
if (lastDatabaseCountryAndYear.keySet().stream().anyMatch(key -> key.toString().equals("MultiKey[IT]"))) {
country = Country.IT;
} else {
Expand Down Expand Up @@ -245,8 +245,8 @@ private static void runGUIlessSetup(int option) throws FileNotFoundException {

// Create EUROMODPolicySchedule input from files
if (!rewritePolicySchedule &&
!new File("input" + File.separator + Parameters.EUROMODpolicyScheduleFilename + ".xlsx").exists()) {
throw new FileNotFoundException("Policy Schedule file '"+ File.separator + "input" + File.separator +
!new File(Parameters.getInputDirectory() + Parameters.EUROMODpolicyScheduleFilename + ".xlsx").exists()) {
throw new FileNotFoundException("Policy Schedule file '"+ File.separator + Parameters.getInputDirectory() +
Parameters.EUROMODpolicyScheduleFilename + ".xlsx` doesn't exist. " +
"Provide excel file or use `--rewrite-policy-schedule` to re-construct from available policy files.");
Comment on lines +249 to 251
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception message is confusing: it prefixes the path with File.separator and includes a stray backtick (). Refactor to show the full path correctly, e.g., "Policy Schedule file '" + fullPath + "' doesn't exist."`.

Suggested change
throw new FileNotFoundException("Policy Schedule file '"+ File.separator + Parameters.getInputDirectory() +
Parameters.EUROMODpolicyScheduleFilename + ".xlsx` doesn't exist. " +
"Provide excel file or use `--rewrite-policy-schedule` to re-construct from available policy files.");
throw new FileNotFoundException("Policy Schedule file '" + Parameters.getInputDirectory() +
Parameters.EUROMODpolicyScheduleFilename + ".xlsx' doesn't exist. " +
"Provide the Excel file or use `--rewrite-policy-schedule` to re-construct it from available policy files.");

Copilot uses AI. Check for mistakes.
};
Expand Down Expand Up @@ -378,7 +378,7 @@ private static void runGUIdialog() {
// call to select policies

// load previously stored values for policy description and initiation year
MultiKeyCoefficientMap previousEUROMODfileInfo = ExcelAssistant.loadCoefficientMap("input" + File.separator + Parameters.EUROMODpolicyScheduleFilename + ".xlsx", country.toString(), 1, 3);
MultiKeyCoefficientMap previousEUROMODfileInfo = ExcelAssistant.loadCoefficientMap(Parameters.getInputDirectory() + Parameters.EUROMODpolicyScheduleFilename + ".xlsx", country.toString(), 1, 3);
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing path separator before the filename; add File.separator between getInputDirectory() and the schedule filename.

Suggested change
MultiKeyCoefficientMap previousEUROMODfileInfo = ExcelAssistant.loadCoefficientMap(Parameters.getInputDirectory() + Parameters.EUROMODpolicyScheduleFilename + ".xlsx", country.toString(), 1, 3);
MultiKeyCoefficientMap previousEUROMODfileInfo = ExcelAssistant.loadCoefficientMap(Parameters.getInputDirectory() + File.separator + Parameters.EUROMODpolicyScheduleFilename + ".xlsx", country.toString(), 1, 3);

Copilot uses AI. Check for mistakes.
Collection<File> euromodOutputTextFiles = FileUtils.listFiles(new File(Parameters.getEuromodOutputDirectory()), new String[]{"txt"}, false);
Iterator<File> fIter = euromodOutputTextFiles.iterator();
while (fIter.hasNext()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public static void databaseFromCSV(Country country, int startYear, boolean isVis
Connection conn = null;
try {
Class.forName("org.h2.Driver");
conn = DriverManager.getConnection("jdbc:h2:file:./input" + File.separator + "input;TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=0;AUTO_SERVER=TRUE", "sa", "");
conn = DriverManager.getConnection("jdbc:h2:file:" + Parameters.getInputDirectory() + "input;TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=0;AUTO_SERVER=TRUE", "sa", "");
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing file separator between getInputDirectory() and input; this may produce an invalid path. Use Parameters.getInputDirectory() + File.separator + "input".

Suggested change
conn = DriverManager.getConnection("jdbc:h2:file:" + Parameters.getInputDirectory() + "input;TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=0;AUTO_SERVER=TRUE", "sa", "");
conn = DriverManager.getConnection("jdbc:h2:file:" + Parameters.getInputDirectory() + File.separator + "input;TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=0;AUTO_SERVER=TRUE", "sa", "");

Copilot uses AI. Check for mistakes.

createTaxDonorTables(conn, country, startYear);
updateDefaultDonorTables(conn, country);
Expand Down Expand Up @@ -606,8 +606,10 @@ public static void populateDonorTaxUnitTables(Country country, boolean showGui)
// establish session for database link
EntityTransaction txn = null;
try {

EntityManager em = Persistence.createEntityManagerFactory("tax-database").createEntityManager();
// access database and obtain donor pool
Map propertyMap = new HashMap();
propertyMap.put("hibernate.connection.url", "jdbc:h2:file:" + Parameters.getInputDirectory() + "input" + ";TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=0;AUTO_SERVER=TRUE");
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path concatenation omits a separator before input, leading to an incorrect JDBC URL. Insert File.separator between the directory and "input".

Suggested change
propertyMap.put("hibernate.connection.url", "jdbc:h2:file:" + Parameters.getInputDirectory() + "input" + ";TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=0;AUTO_SERVER=TRUE");
propertyMap.put("hibernate.connection.url", "jdbc:h2:file:" + Parameters.getInputDirectory() + File.separator + "input" + ";TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=0;AUTO_SERVER=TRUE");

Copilot uses AI. Check for mistakes.
EntityManager em = Persistence.createEntityManagerFactory("tax-database", propertyMap).createEntityManager();
txn = em.getTransaction();
txn.begin();

Expand Down
4 changes: 4 additions & 0 deletions src/test/java/simpaths/model/PersonTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class WithLawrenceParameters {
@BeforeEach
public void setupLawrenceCoefficients() {

Parameters.setInputDirectory("src/test/java/simpaths/testinput");
Copy link

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Modifying a global Parameters directory in @beforeeach without resetting it may lead to state leakage between tests; consider using JUnit's @tempdir or resetting to a default value in an @AfterEach.

Copilot uses AI. Check for mistakes.

Parameters.eq5dConversionParameters = "lawrence";
Parameters.loadEQ5DParameters("UK", 8);

Expand Down Expand Up @@ -70,6 +72,8 @@ class WithFranksParameters {
@BeforeEach
public void setupFranksCoefficients() {

Parameters.setInputDirectory("src/test/java/simpaths/testinput");

Parameters.eq5dConversionParameters = "franks";
Parameters.loadEQ5DParameters("UK", 8);

Expand Down
Binary file added src/test/java/simpaths/testinput/reg_eq5d.xlsx
Binary file not shown.