From 3aa0cd85a2fb67b5b14703a44d11fe9c1a301b95 Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Fri, 19 Jan 2024 22:10:24 +0000 Subject: [PATCH 01/16] Refactor package names and add regression test data --- .../com/arup/cml/{ => abm}/kpi/DataModel.java | 0 .../cml/{ => abm}/kpi/KPIDomainModel.java | 0 .../cml/{ => abm}/kpi/matsim/MATSimModel.java | 50 +- .../kpi/matsim/handlers/LinkLogHandler.java | 0 .../kpi/matsim/run/KpiGenerator.java | 0 .../matsim/RelaxedReflectiveConfigGroup.java | 20 - .../arup/cml/{ => abm}/kpi/TableHelpers.java | 0 .../cml/{ => abm}/kpi/matsim/TestNothing.java | 0 .../matsim/handlers/TestLinkLogHandler.java | 0 .../TestLinkLogHandlerWithMultipleAgents.java | 0 .../TestLinkLogHandlerWithSimpleData.java | 0 .../output_allVehicles.xml.gz | Bin 0 -> 566 bytes .../smol-matsim-outputs/output_config.xml | 1394 +++++++++++++++++ .../output_config_reduced.xml | 589 +++++++ .../smol-matsim-outputs/output_counts.xml.gz | Bin 0 -> 194 bytes .../smol-matsim-outputs/output_events.xml.gz | Bin 0 -> 4280 bytes .../output_facilities.xml.gz | Bin 0 -> 140 bytes .../output_households.xml.gz | Bin 0 -> 176 bytes .../smol-matsim-outputs/output_legs.csv.gz | Bin 0 -> 729 bytes .../smol-matsim-outputs/output_network.xml.gz | Bin 0 -> 722 bytes .../smol-matsim-outputs/output_persons.csv.gz | Bin 0 -> 336 bytes .../smol-matsim-outputs/output_plans.xml.gz | Bin 0 -> 2334 bytes .../output_transitSchedule.xml.gz | Bin 0 -> 627 bytes .../output_transitVehicles.xml.gz | Bin 0 -> 488 bytes .../smol-matsim-outputs/output_trips.csv.gz | Bin 0 -> 867 bytes .../output_vehicles.xml.gz | Bin 0 -> 594 bytes 26 files changed, 2013 insertions(+), 40 deletions(-) rename src/main/java/com/arup/cml/{ => abm}/kpi/DataModel.java (100%) rename src/main/java/com/arup/cml/{ => abm}/kpi/KPIDomainModel.java (100%) rename src/main/java/com/arup/cml/{ => abm}/kpi/matsim/MATSimModel.java (80%) rename src/main/java/com/arup/cml/{ => abm}/kpi/matsim/handlers/LinkLogHandler.java (100%) rename src/main/java/com/arup/cml/{ => abm}/kpi/matsim/run/KpiGenerator.java (100%) delete mode 100644 src/main/java/com/arup/cml/kpi/matsim/RelaxedReflectiveConfigGroup.java rename src/test/java/com/arup/cml/{ => abm}/kpi/TableHelpers.java (100%) rename src/test/java/com/arup/cml/{ => abm}/kpi/matsim/TestNothing.java (100%) rename src/test/java/com/arup/cml/{ => abm}/kpi/matsim/handlers/TestLinkLogHandler.java (100%) rename src/test/java/com/arup/cml/{ => abm}/kpi/matsim/handlers/TestLinkLogHandlerWithMultipleAgents.java (100%) rename src/test/java/com/arup/cml/{ => abm}/kpi/matsim/handlers/TestLinkLogHandlerWithSimpleData.java (100%) create mode 100644 src/test/regression/data/smol-matsim-outputs/output_allVehicles.xml.gz create mode 100644 src/test/regression/data/smol-matsim-outputs/output_config.xml create mode 100644 src/test/regression/data/smol-matsim-outputs/output_config_reduced.xml create mode 100644 src/test/regression/data/smol-matsim-outputs/output_counts.xml.gz create mode 100644 src/test/regression/data/smol-matsim-outputs/output_events.xml.gz create mode 100644 src/test/regression/data/smol-matsim-outputs/output_facilities.xml.gz create mode 100644 src/test/regression/data/smol-matsim-outputs/output_households.xml.gz create mode 100644 src/test/regression/data/smol-matsim-outputs/output_legs.csv.gz create mode 100644 src/test/regression/data/smol-matsim-outputs/output_network.xml.gz create mode 100644 src/test/regression/data/smol-matsim-outputs/output_persons.csv.gz create mode 100644 src/test/regression/data/smol-matsim-outputs/output_plans.xml.gz create mode 100644 src/test/regression/data/smol-matsim-outputs/output_transitSchedule.xml.gz create mode 100644 src/test/regression/data/smol-matsim-outputs/output_transitVehicles.xml.gz create mode 100644 src/test/regression/data/smol-matsim-outputs/output_trips.csv.gz create mode 100644 src/test/regression/data/smol-matsim-outputs/output_vehicles.xml.gz diff --git a/src/main/java/com/arup/cml/kpi/DataModel.java b/src/main/java/com/arup/cml/abm/kpi/DataModel.java similarity index 100% rename from src/main/java/com/arup/cml/kpi/DataModel.java rename to src/main/java/com/arup/cml/abm/kpi/DataModel.java diff --git a/src/main/java/com/arup/cml/kpi/KPIDomainModel.java b/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java similarity index 100% rename from src/main/java/com/arup/cml/kpi/KPIDomainModel.java rename to src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java diff --git a/src/main/java/com/arup/cml/kpi/matsim/MATSimModel.java b/src/main/java/com/arup/cml/abm/kpi/matsim/MATSimModel.java similarity index 80% rename from src/main/java/com/arup/cml/kpi/matsim/MATSimModel.java rename to src/main/java/com/arup/cml/abm/kpi/matsim/MATSimModel.java index d4dc6a1..6295f52 100644 --- a/src/main/java/com/arup/cml/kpi/matsim/MATSimModel.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/MATSimModel.java @@ -8,7 +8,9 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; +import org.matsim.core.config.ReflectiveConfigGroup; import org.matsim.core.config.groups.*; import org.matsim.core.events.EventsUtils; import org.matsim.core.events.MatsimEventsReader; @@ -18,8 +20,7 @@ import tech.tablesaw.api.StringColumn; import tech.tablesaw.api.Table; -import java.util.ArrayList; -import java.util.Arrays; +import java.util.*; public class MATSimModel implements DataModel { @@ -28,16 +29,15 @@ public class MATSimModel implements DataModel { private final String matsimOutputDir; private final Scenario scenario; private final EventsManager eventsManager; - - private final String[] necessaryConfigGroups = new String[]{ - GlobalConfigGroup.GROUP_NAME, - PlansConfigGroup.GROUP_NAME, - FacilitiesConfigGroup.GROUP_NAME, - HouseholdsConfigGroup.GROUP_NAME, - TransitConfigGroup.GROUP_NAME, - VehiclesConfigGroup.GROUP_NAME, - NetworkConfigGroup.GROUP_NAME - }; + private final Set necessaryConfigGroups = new HashSet<>(Arrays.asList( + GlobalConfigGroup.GROUP_NAME, + PlansConfigGroup.GROUP_NAME, + FacilitiesConfigGroup.GROUP_NAME, + HouseholdsConfigGroup.GROUP_NAME, + TransitConfigGroup.GROUP_NAME, + VehiclesConfigGroup.GROUP_NAME, + NetworkConfigGroup.GROUP_NAME + )); private final Table linkLog; private final Table vehicleOccupancy; @@ -65,18 +65,28 @@ public MATSimModel(String matsimInputConfig, String matsimOutputDir) { private Config getConfig(String matsimInputConfig) { Config config = ConfigUtils.createConfig(); - ArrayList configGroups = new ArrayList<>(config.getModules().keySet()); - for (String module : configGroups) { - if (Arrays.asList(necessaryConfigGroups).contains(module)) { +// TreeMap configuredModules = config.getModules(); +// for (ConfigGroup module : configuredModules.values().stream().toList()){ +// for (Map.Entry entry : module.getParams().entrySet()) { +// System.out.println((entry.getKey() + "," + entry.getValue())); +// } +// } + + TreeMap configuredModules = config.getModules(); + for (ConfigGroup module : configuredModules.values().stream().toList()) { + if (necessaryConfigGroups.contains(module.getName())) { System.out.println("Config group " + module + " is read as is"); } else { - config.removeModule(module); - config.addModule(new RelaxedReflectiveConfigGroup(module)); + ReflectiveConfigGroup relaxedModule = + new ReflectiveConfigGroup(module.getName(),true) {}; +// for (Map.Entry entry : module.getParams().entrySet()) { +// relaxedModule.addParam(entry.getKey(), entry.getValue()); +// } + config.removeModule(module.getName()); + config.addModule(relaxedModule); } } - ConfigUtils.loadConfig( - config, String.format(matsimInputConfig) - ); + ConfigUtils.loadConfig(config, String.format(matsimInputConfig)); setOutputFilePaths(config); return config; } diff --git a/src/main/java/com/arup/cml/kpi/matsim/handlers/LinkLogHandler.java b/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/LinkLogHandler.java similarity index 100% rename from src/main/java/com/arup/cml/kpi/matsim/handlers/LinkLogHandler.java rename to src/main/java/com/arup/cml/abm/kpi/matsim/handlers/LinkLogHandler.java diff --git a/src/main/java/com/arup/cml/kpi/matsim/run/KpiGenerator.java b/src/main/java/com/arup/cml/abm/kpi/matsim/run/KpiGenerator.java similarity index 100% rename from src/main/java/com/arup/cml/kpi/matsim/run/KpiGenerator.java rename to src/main/java/com/arup/cml/abm/kpi/matsim/run/KpiGenerator.java diff --git a/src/main/java/com/arup/cml/kpi/matsim/RelaxedReflectiveConfigGroup.java b/src/main/java/com/arup/cml/kpi/matsim/RelaxedReflectiveConfigGroup.java deleted file mode 100644 index 105f7d9..0000000 --- a/src/main/java/com/arup/cml/kpi/matsim/RelaxedReflectiveConfigGroup.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.arup.cml.kpi.matsim; - -import org.matsim.core.config.ReflectiveConfigGroup; - -public class RelaxedReflectiveConfigGroup extends ReflectiveConfigGroup { - - public RelaxedReflectiveConfigGroup(String name) { - super(name, true); - } - -// @Override -// public void handleAddUnknownParam(final String paramName, final String value) { -// System.out.println("hey"); -// } - -// @Override -// public String handleGetUnknownValue(final String paramName) { -// return "hello"; -// } -} diff --git a/src/test/java/com/arup/cml/kpi/TableHelpers.java b/src/test/java/com/arup/cml/abm/kpi/TableHelpers.java similarity index 100% rename from src/test/java/com/arup/cml/kpi/TableHelpers.java rename to src/test/java/com/arup/cml/abm/kpi/TableHelpers.java diff --git a/src/test/java/com/arup/cml/kpi/matsim/TestNothing.java b/src/test/java/com/arup/cml/abm/kpi/matsim/TestNothing.java similarity index 100% rename from src/test/java/com/arup/cml/kpi/matsim/TestNothing.java rename to src/test/java/com/arup/cml/abm/kpi/matsim/TestNothing.java diff --git a/src/test/java/com/arup/cml/kpi/matsim/handlers/TestLinkLogHandler.java b/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandler.java similarity index 100% rename from src/test/java/com/arup/cml/kpi/matsim/handlers/TestLinkLogHandler.java rename to src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandler.java diff --git a/src/test/java/com/arup/cml/kpi/matsim/handlers/TestLinkLogHandlerWithMultipleAgents.java b/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandlerWithMultipleAgents.java similarity index 100% rename from src/test/java/com/arup/cml/kpi/matsim/handlers/TestLinkLogHandlerWithMultipleAgents.java rename to src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandlerWithMultipleAgents.java diff --git a/src/test/java/com/arup/cml/kpi/matsim/handlers/TestLinkLogHandlerWithSimpleData.java b/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandlerWithSimpleData.java similarity index 100% rename from src/test/java/com/arup/cml/kpi/matsim/handlers/TestLinkLogHandlerWithSimpleData.java rename to src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandlerWithSimpleData.java diff --git a/src/test/regression/data/smol-matsim-outputs/output_allVehicles.xml.gz b/src/test/regression/data/smol-matsim-outputs/output_allVehicles.xml.gz new file mode 100644 index 0000000000000000000000000000000000000000..90ec1c6e83a5451437d995a8082cd2b8773d7165 GIT binary patch literal 566 zcmV-60?GX!iwFP!000000JT)nZrU&ueWqVwS$nM$LQyM}P-&x;kXmh8S+%#xI5)&? zY-hGZ;P2-c0+cechfYEYzW3a7eU7gk->yV~mY@w+GQoWkVg!<@l*>hef6VSLZ}9E- z;v!x`&RGEy$hhRzfemt%(j+*ywj2dPUDrfVYq%gvFM^C0V1m@9c!L|Q41a^I2ObxN zVL$l!`0&JX5cHBuW2t1|stg|)AAC@ZTED%HR;VK%ych9n8Ih2zOp2YzUaNApE&=g0 z!JjMR61`qbt<`*9SuoA=V2vadkYLIf7&GGnrt%4xlBxLy+Wm}@7_ovH=hO>bQc_U4 zAQM&13&7)$M8i1Pk)7sFmC|2J(B6bcmBNnDscVI9cW%h@Uc#rzyUMWv&1uou6Bhb| z^c*a`cQKzWZJAC3U^5K_zpZMAxLhWt3oR zrC%FM(ZT-&Gpe_ctWfn`mT|`2eOljBW|c;n|7`AA1B-)$i90!g4dG_P$G%ueN<2fMd{+-}EjH7T;K5)A{UCq$z5lzt-r9L(`WRW4+FW#BaRi9E z0D~^TRTp4*7Qk}NO^aydzd@u>aQA?(&w^f5PUTsI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/regression/data/smol-matsim-outputs/output_config_reduced.xml b/src/test/regression/data/smol-matsim-outputs/output_config_reduced.xml new file mode 100644 index 0000000..dee0eda --- /dev/null +++ b/src/test/regression/data/smol-matsim-outputs/output_config_reduced.xml @@ -0,0 +1,589 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/regression/data/smol-matsim-outputs/output_counts.xml.gz b/src/test/regression/data/smol-matsim-outputs/output_counts.xml.gz new file mode 100644 index 0000000000000000000000000000000000000000..d0ba19fcf74ff99b1b7128486fda5b8a2b9fa9d1 GIT binary patch literal 194 zcmV;z06qU7iwFP!000000IiO}4uUWcMDP8Ib?>F17egrCJfRmg@n)J*v5DOpwgUdW zMEwNkI+ORN+DzdNgX`Hx(pY3Uf+HJSPo2ioaVyujsYPYulM=%`CN3xT8gD5*N~Oke z%*Is~`%W$Myin&|bFeoTjP%6GkaZ~LeMxa|g5!s=?%Oxfn)H$WNWmob;X}ImyJOX+ wR(-vfp~xm~Q2@;ljR-GidX4j0s6kWeVmLpO-gZ`ptH+UcH`Vf1gcm`qka~ zezE%Sdh)b;n6{H&-u(2c|I)8^TlgQ}{PefO-*0w{&;9F3UYE1k0I>V^=swQxcKzyp za`WhZGyLR3zuA17+$XYipC6xg^PL;YeEFaC)6R|d@crXXL2|y?EWXT_ z27)r=-EO;c;}E8+dYP>X&eh}YX0h7!8}|n{CLKL_agtH9t}j@snrzTY~8Jp+gDzpgi*4&N^VLvFYUzVDX{w|h=Q zZl?8dj$bCZn4t~eW^JvYL`*J8>@>f3^9?t_`>#c+@AjnrIf%jbum0oWZb{Pra`@`< zPa^d3H%<=?;5WO?{NZ77Cyb6DwCZ=mqFsz?(=XkKzx40c+r{pz@Mw;*Ge^t*VYeqH zkra{kW9sh#SUs(@V9o4uqW;{>S8gD`ZiXNHF{qEN6Wsl$f87r|<@Wv4HoN`D)Aocv z{C)W2WSG|B$G(>X=j!dc3n2>$MwU*Z9sWqnyjako}$8IBByVRR`BH^k-9D|w z-AXQB2^Nt7sxE*=_|h;E_~J^JZAgaOs!-YldQTc)^6}{Xw1D8M49G{L_lW!0SMc7qYBK-wofqB^lC!pgLxN+$^L5*iKeH_qf0ewU< zc&tMdMKqB?%JoNG*tLZ)@>$0rH5W*dlMEsVB#9Vf4)Vetg!&K(1obqmKO)g1Mu?t* z^&y>tEzcL(_+$zySVxEpJKOd_BZQryauL8kGFs;bLV5z@4@V&| zEh{iSBor9+iQHy6cN<_?Vt_;|m{tvzCp(QbHvx_ucN{BEQHVm%fa*%2%}eekz%-Ag za1YQ5reyb9U7QQpAu6F}v!# znRiWP3G-1xftM&sJ(#%pE()vSubk;Q5P>wIJ}s8Vl;wmFx#|pOSIs(NhVj*sFNOmT z99G3KWg1>3aMc=&uZEo~t=-W`6ID!eB@pX|=%*V1X@Wc)RudPbJ!h9(25E~t6s08z zj!S15Lr^l%h#WI&d85=_qjt}Y>2wg;GtWX}lP$D{b)ZdKQu3cmgEQWmlQeTGNi$E9 zr1^PqFQsTghJz`ZxjjV_A}dlfb6=(c)>zA#exK&s#T;eH4Ni9(&bAJl%hK#n#MBoD z!8pHR>W&PYChhoH1eJ^|YG9ZM&^U*|7*vjlosbkFVTsa#EfLBPj-5Oz&(=|7jZAvh zMIg=T%VM!bM`;;o6Jm+?=K@UJAilutm=)pQ}3y(&k*fNwdIgJpJaeIw2Eyz*Qm@ zpA0I-lr>d?$Dn0F6XfGE+HE2RWxOPa5Rg6hDv!v$>XO%F^0WPaDa`DySC|Q*N1P6( zM4Rr1D+BHLGElA5izT4mrKJWarYcot$xw~gHTI08fRrdRlDg)ymJRRghxxAmd~#g( zVP050FjePsLqf!kCTN}Z^ZUi8p4-re??tNYj((wkn%kE@h_KTBB1YyB0ekB(9Lwh7 ziyPJMDg;t^nJg4%5Yn?C;>Z^UVW{BjbT6Sw~b^ zSwGM}&Dr6j2r0=qF)BnNM#_cddvIa_oS*0YPtN8?qNVfbL}oVQVPW%FqNkZCWE)dc zHNHd1h;>Ou%(OmZx}hL?bT^a($zwB=Z$^Vma2mXf(jUu>dKd5mac;b!U|pSXv_SHS-Kt;2#aLR(08Jk zrR!mVutK|0n<`MuDqHqWK-E;{?41x$!`6K&9Up`v$0%5&xEP-?lZGZZ?h0cJL0#%j z&Zh3fU0WlD6sbGfGz)|rNZs+rCI!MB?hn_z1M!sdG66xSYTkiizen>9pXRljcOZ)2 zt$7D24{74+1N4v9ykp=gRr3ynMV`5aUJ1nvG^9{v)D=`lU6CZC&P`}9q|_mfgDG`| zIi(IED^ltTU)PhjR|r{`jpYvj(TS4Cn(#&iOQML$#u_MUyB;1QCYo7I)-wcQX&g%) zE?v(MgcWiC^sY|2<^u>T+TSR3KpE%HYU2n1MNTMS zfReQ)Kv;@vBo-~3)tRqNLl!PbwIw~RsJI?vhBa-~$;1fMGiv=I$#(z<(lcm%%;$6E z5H%BN{?LC5$J!c*)Rf#u3qPLi~{;9}P6*(g$IuxlbVRK*|&z4GuKomtN zGK}PoLA7#Zu6!YmtR7jY%yPyD1JMvibG|cBKUirx;wY)-pIxCe9fMxEG`+}5TM{8{ zIY1Oys2L!85@9huiEyB&ZQ!PL3LqqVd#-8UhVj_D^CZpGe2T&A^J~x(ZqQToZX3Tw zVe4kZD%EG>rdH-#qI*$ z?Y;&mqTzvpC4EN#2WHQC4M>SD=e5XEbu&OnaykGHmZ}IFA;|^;4@OmTj@!kWC{4zf zacX53v->n-O9m4oedHtZ&o#!$JwpGNy0U`Jkv+Q@cia zs%k}qMD1#QjiCceRIP}RD7N$^E=6A05_M=z3Q_35d9DNc!HOplM@gd|`4x&MF=&$F z$-onfj+Q-%DR9Z7%PArWj=NPFLr|B*RIo`*k+;2&Aw?3C`eGX*2a=flvB?5iXYAFk zHXsUdG#8XXsG`f+B#v=7io38NQrR_z1{q2i*`EvoRdvAy#7CjXzDf|N&Z(Nb&^ElR zRiX$)*<6qnb^~fFu^^|@jCIvM^8+v3Eu6A-K7x@o4u{lnN_iZN932QFb+e8;xW>WIwsEFI$|_DN zkAopkE$z^9DlDsdHzD=Qi-;FiFY7lf1m)jNP$ec}ME>1`nCCsKj(y5L)d|o^PuNSR zm%SJo(M(YcjUXk>d`$yGShrNUJ@UednMwA#P|M1xGpvkjcikK^VfB)AB$Jm<>ZfKm zi42RU?g}T&SE^^awcTabp-mdQ7zF+gt>xq{*5`W6VO2vf1k#a~a7aBJRLMvxX z>$=BRUB#Agj|B=v(^Rh!R9!8$C>jGqGL!Ap=tqy zIGQ6h2$h#b1BTCZZj8v4Ky<{$jcMXHh$>${s!v-%u#!7+?c|(+9Zo}PYf})89ARgm z3edPpRUuwd72=MZzCwI|~e|fG_7e-j73f03LK8lc{g2N+11fnbne$`Ut zTguBOW{cW`)RvV~=DZqL?y4!hMqWbd6=}f;{|Ygr%OWckMFPPF7RD*K=G)x^D}2<8 zpeMovoR-RtB$+LYs**z7C*$%guWOkw${X8Ey|T9x<=m) ziVdaeWmAfz!tCxaP+_loQK+1tzA0>VF9EZ%FxR~VfJ&hcsBR8RDS`}h+QUFq#f6VY zp-}8J%5l|vF95A#sHIi_m8uJj1Ii7#kC%rPHQ=bT3UI=PkJQ#bfb@b#-e_d64gz|C zBMP$gXTYG=BVZ+ew|Pb%- aQ|JO>dz19l&wEnaH~#}1HRWTjwEzGB<0Tvb literal 0 HcmV?d00001 diff --git a/src/test/regression/data/smol-matsim-outputs/output_facilities.xml.gz b/src/test/regression/data/smol-matsim-outputs/output_facilities.xml.gz new file mode 100644 index 0000000000000000000000000000000000000000..9b8ac4f552ad564765765b5b341860774dca7b19 GIT binary patch literal 140 zcmb2|=3sz;%^TOBI2)+pt*dqJ%=yisMpujjf;`T8pYuO?#(R4x7jNO^tpS_1Ki(8r z^0Az+lcylm!`tWFnUgvveRRV(`gr&XzlH{!($Li0aOt|fzW(*ozB-!c&RjjM?{(e( s^chdxYyO&^7u_>D^^GqvcWK-#EWD}U(s)dHL^X{~uiy?e$PB^KFn`zogoAkr*R?5$p z;Gj;dchBYS>TY(HOlm|Ed;=vdfG975G=6B{dO79?=-Mo+b$FrD!Ac}c!eawE#%IM? zN{Koi(Ks5$fjx{>$Yhl8;i?(UADi|ow=0U0-A?^kXytfrJVx$?T2g2#T*W>J9@kkL eRb<0w-|_cpxkzV}&}Q|I-o6157F78O0RRAF_fb0l literal 0 HcmV?d00001 diff --git a/src/test/regression/data/smol-matsim-outputs/output_legs.csv.gz b/src/test/regression/data/smol-matsim-outputs/output_legs.csv.gz new file mode 100644 index 0000000000000000000000000000000000000000..2b864843c8ac11fd387d8182a4924165422dfc33 GIT binary patch literal 729 zcmV;~0w(<*iwFP!000000KJy$ZksR^$G=b7qcHhOh|j}B6uibu0uj(l-hTG64F=P# znxaNjn>st-hAEwjQ zbeG`1hwB4$*ZL2f^N#ibb<^l^JdIP2O8R+7Z>?T88szEuX6Rog4X^ranya>d_5E9O z9?S@6PZY>O@k$8-geY=Ul%eB(K}u_ydH`B*DD2G-0tLg1C?tpy-3qPyLFAgxfR>6% zB}#{-L`kvm%gE1YxnRQoSx@>_gTJ^4DrH3&g1J=kuqe=jHBaWE;aF6TjYPQ(fzA>h zy4A2z92B#3i>8Vn72}JBm^CtDE}CjQ>tT2RT3-i-ycxVWwtub{Op2!$V$PCuj*RF( zL77mLhbj>2i+i6o5Ep_Za;e0*ziHoKwvXVgA13JUhd`UVHvQx#5? zNK(UGRWK=T(hf4I_5Rr%GNq?yr*8eFbUD*=Sf;nohu*fnGpn;xS5_f5dB?RuMPciG z2#Yn_ugmEjH09%R4X0;{SU+9f)y`V-tUbYn|EoXO9ia7{BW2P#NCcs`@q(5njw& z1F36?brc^;WVk)eM55JK^QvvVqZ4*|tOymWbXDmr%aloZK}CEQiKQTsyC=o)yFn}n z<%%5>DH4mnL#~QroQ}^3@l}`Em{=N98H6^_EX2R52>hb(C7F{r_+OB@65kj9H*>!M LBXdlK&I$kk-56!w literal 0 HcmV?d00001 diff --git a/src/test/regression/data/smol-matsim-outputs/output_network.xml.gz b/src/test/regression/data/smol-matsim-outputs/output_network.xml.gz new file mode 100644 index 0000000000000000000000000000000000000000..b944f665ae37cb0da7ac03789a7c633f6540a111 GIT binary patch literal 722 zcmV;@0xkU?iwFP!000000L_@+Z<{a>$Dfd*^okjk=2QDk^&=6 zBE~}SD>_705@lO!C0w&DSS)W=UuMYnA)MPU^NHD8cT6tGG>!0|d<@ep*OKMyY8mp% zplcCMU_6BY%AlUA-_pRA7K$k>Z6^@c<_?CJJsi~o^?9Ju!~Y8pSM_lFJiO8)Xgs_g z5A-TXW{>q52*W=Ls#hD=);*JB)!u=Z9VVrN)8M#04!(ll7tTP<@kQ(DIa`;abG{ID z`W_NUXtrZU9PRg{pt%5o&J05F6-{NcAu*>15|boh^tVvAZ{gOs5HUH@HGdF6v3v|l zYB}M#tW1&kO_8UisCZr$LPD~ww6E5?DF|VELP|Bs0Ra-ll(+IIxKjBbR<*iZJTp3# zbEYyZA-JbIGCoGhZX8F&`2LZN<5QfFI*JlVA%mt=V#Nl}aB`%ktDmh6536*zfeW;< zIi>?&;HtdJk%5Fx;Gqs48Vnw47akg1;R!sqgXazg&uu5y9b9q+p4Y+i27~9dlj{vF zxv1GKP-nOBb&`p+)?{^32eOa3CQ``IU}EMeWZtWoX+-myLi64_mS{!83K||rrFr5% zuCu$GQe-iKquKmA)7R0o>mo18Wl`BD$tGQD`@^e8m`~u z)9>U{D_PKJAn0g7Z|exmse(3bp=s6Uv}w50Zo~cmXy=P}c?U7KUtTXh0~(@>FWVFV E0H?)SqW}N^ literal 0 HcmV?d00001 diff --git a/src/test/regression/data/smol-matsim-outputs/output_persons.csv.gz b/src/test/regression/data/smol-matsim-outputs/output_persons.csv.gz new file mode 100644 index 0000000000000000000000000000000000000000..00cf00050d130db6c54f4e73c918cfd4c79e6afe GIT binary patch literal 336 zcmV-W0k8faiwFP!000000DY0&Zo?o9M(->29rgl^3gm=88Rz#t^>bTJF?IW0 z)eLbIg}P8^to4RSS>xqk0Sb_VUXCVRf;92myv44{^?r9Mr*J7n0T!Tv5lDd{i%LAK zq@p8A{OMpI!}m78%J4wrR+w=vJF?se%TUpJn{@qvl6oZ{Whc=j`BQndzBM0duuS? zEYFSJ4EK?mvRgbA8Ft<~2IEi*@ruGG`dN-KFGF!*9C)uiDrRlH82_vKr)wSB_!aKH iz5ol}{<_LA(v4^+ZR8scXS{ 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 literal 0 HcmV?d00001 diff --git a/src/test/regression/data/smol-matsim-outputs/output_trips.csv.gz b/src/test/regression/data/smol-matsim-outputs/output_trips.csv.gz new file mode 100644 index 0000000000000000000000000000000000000000..a05d676762a070d873913fda0bd34c866a03216c GIT binary patch literal 867 zcmV-p1DyOHiwFP!000000L7N;j+-zLh5uLTqfq(E#eNvX1}E!=00OezynV-G2YHUxgj!JyV%7FKs^* z^~q>+KUKCgMLlob3R~y5rZl>0>Wk@z=SP0m4ZVh)Zpe$%VBhTU$cIM@Usji^9e>xk zIN8eWfj+-e+4?#z-^clZkB7IqYrN4d-f?{Bv+Y1pJLE4-(UrEoROgdA#Y{2Am@u4c2kmOUUID+|7RP2Ki|4~$JPgfA-CLby>i2{Kn zI1(atL!8EkM)+8{aS@UfW)vKj?T{*9%2}z81Z8y&h+u zYx1mZIMp<$ZSLAFmHdO+rX->iZHnNwtKf~VC_X=^S2-u~m?3=+V zpO$0GpK?ycBJimTd=iUv4m|uwYINB(ZF4@u!_W31H|{BqsF>b3LT*H`Sp>u17gN$H zS1b!e5MT7cdw%9mD|XDp57H=`4*XgNpLOuX0f1nzFc>iggUYQA_FVB@+i0 t@TbQYGV(vhOgUS5&6DO!dELqsMM{MDz(zIcGK=E*Et~` ziOp<7;NS1WkWyBND~(FK*cEX6__fay6M1yGEQ??P+6W~R64QtTAh}9~oFwGi|Kj2{TcE2~(SrH8)%uvBOqf z$91A84u9O=J@6b#b|$2;Ome_kMhuNB-YL$k+n#5sz%w4cZQ^Osp%Go0lwgx5O_z_W z83ZCt$kp7qfs+wuGscBo1qLuVA$=58Z?zWnRjKk;enE+<7Sf3}bHZlQxc*guoY*`l z!GcE9xGo9ZKqb;`y+bcH<&rH$IWNCMq1?g_z(pQ_D~WsSc3%>>GWJ$xN|#Plv-+P^ zEY6rQxDU{un7;ls7Yl~lvL={uSU>%BpafefJ-t^c1h2j)Ch#;s0m& zgU>K$`helyUmfA|m*cXdciZAWskgRqRJ|1|rXTW(i1z#4mVJI>+U*_t4H5hNIvvLl z?BwF&OA=Td+CI5Az*GH~*+9*|X9vP!+yGYxfQ}F7`hcDf=(hqq*TS^+>IiSMDHH;4 zOsm$Y2J)t5%;FuVHEWIdlQg95IS6=D@L+mcbA&hNr^=aZ&2fY`XUdFd*W(Cpjud>_ g8dC$_6s Date: Tue, 23 Jan 2024 03:36:46 +0000 Subject: [PATCH 02/16] Refactor packages and add an integration test --- .gitignore | 1 + dependency-reduced-pom.xml | 2 +- pom.xml | 2 +- .../java/com/arup/cml/abm/kpi/DataModel.java | 2 +- .../com/arup/cml/abm/kpi/KPIDomainModel.java | 2 +- .../java/com/arup/cml/abm/kpi/KpiApi.java | 6 + .../java/com/arup/cml/abm/kpi/LinkLog.java | 4 + .../arup/cml/abm/kpi/matsim/MATSimModel.java | 6 +- .../kpi/matsim/handlers/LinkLogHandler.java | 2 +- .../cml/abm/kpi/matsim/run/KpiGenerator.java | 7 +- .../cml/abm/kpi/tablesaw/TablesawKpiApi.java | 6 + .../com/arup/cml/abm/kpi/TableHelpers.java | 2 +- .../KpiGeneratorIntegrationTest.java | 48 ++ .../arup/cml/abm/kpi/matsim/TestNothing.java | 2 +- .../matsim/handlers/TestLinkLogHandler.java | 2 +- .../TestLinkLogHandlerWithMultipleAgents.java | 4 +- .../TestLinkLogHandlerWithSimpleData.java | 4 +- .../output_config_reduced.xml | 589 ------------------ .../smol-matsim-outputs/output_counts.xml.gz | Bin 194 -> 0 bytes .../smol-matsim-outputs/output_legs.csv.gz | Bin 729 -> 0 bytes .../smol-matsim-outputs/output_persons.csv.gz | Bin 336 -> 0 bytes .../smol-matsim-outputs/output_trips.csv.gz | Bin 867 -> 0 bytes .../smol-matsim-outputs/expected-kpi.csv | 2 + .../output_allVehicles.xml.gz | Bin .../smol-matsim-outputs/output_config.xml | 1 - .../smol-matsim-outputs/output_events.xml.gz | Bin .../output_facilities.xml.gz | Bin .../output_households.xml.gz | Bin .../smol-matsim-outputs/output_network.xml.gz | Bin .../smol-matsim-outputs/output_plans.xml.gz | Bin .../output_transitSchedule.xml.gz | Bin .../output_transitVehicles.xml.gz | Bin .../output_vehicles.xml.gz | Bin 33 files changed, 86 insertions(+), 608 deletions(-) create mode 100644 src/main/java/com/arup/cml/abm/kpi/KpiApi.java create mode 100644 src/main/java/com/arup/cml/abm/kpi/LinkLog.java create mode 100644 src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiApi.java create mode 100644 src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java delete mode 100644 src/test/regression/data/smol-matsim-outputs/output_config_reduced.xml delete mode 100644 src/test/regression/data/smol-matsim-outputs/output_counts.xml.gz delete mode 100644 src/test/regression/data/smol-matsim-outputs/output_legs.csv.gz delete mode 100644 src/test/regression/data/smol-matsim-outputs/output_persons.csv.gz delete mode 100644 src/test/regression/data/smol-matsim-outputs/output_trips.csv.gz create mode 100644 src/test/resources/integration-test-data/smol-matsim-outputs/expected-kpi.csv rename src/test/{regression/data => resources/integration-test-data}/smol-matsim-outputs/output_allVehicles.xml.gz (100%) rename src/test/{regression/data => resources/integration-test-data}/smol-matsim-outputs/output_config.xml (99%) rename src/test/{regression/data => resources/integration-test-data}/smol-matsim-outputs/output_events.xml.gz (100%) rename src/test/{regression/data => resources/integration-test-data}/smol-matsim-outputs/output_facilities.xml.gz (100%) rename src/test/{regression/data => resources/integration-test-data}/smol-matsim-outputs/output_households.xml.gz (100%) rename src/test/{regression/data => resources/integration-test-data}/smol-matsim-outputs/output_network.xml.gz (100%) rename src/test/{regression/data => resources/integration-test-data}/smol-matsim-outputs/output_plans.xml.gz (100%) rename src/test/{regression/data => resources/integration-test-data}/smol-matsim-outputs/output_transitSchedule.xml.gz (100%) rename src/test/{regression/data => resources/integration-test-data}/smol-matsim-outputs/output_transitVehicles.xml.gz (100%) rename src/test/{regression/data => resources/integration-test-data}/smol-matsim-outputs/output_vehicles.xml.gz (100%) diff --git a/.gitignore b/.gitignore index acc6b3c..a3f1b32 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ hs_err_pid* replay_pid* target/ +gelato.iml diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index c242f67..67a044c 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -220,7 +220,7 @@ 17 - com.arup.cml.kpi.matsim.run.KpiGenerator + com.arup.cml.abm.kpi.matsim.run.KpiGenerator 17 UTF-8 17 diff --git a/pom.xml b/pom.xml index 12fc6cb..31eaca0 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ UTF-8 UTF-8 17 - com.arup.cml.kpi.matsim.run.KpiGenerator + com.arup.cml.abm.kpi.matsim.run.KpiGenerator 17 17 diff --git a/src/main/java/com/arup/cml/abm/kpi/DataModel.java b/src/main/java/com/arup/cml/abm/kpi/DataModel.java index 6e940d3..ff67f2b 100644 --- a/src/main/java/com/arup/cml/abm/kpi/DataModel.java +++ b/src/main/java/com/arup/cml/abm/kpi/DataModel.java @@ -1,4 +1,4 @@ -package com.arup.cml.kpi; +package com.arup.cml.abm.kpi; import tech.tablesaw.api.Table; diff --git a/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java b/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java index b48c5dc..5f5550c 100644 --- a/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java +++ b/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java @@ -1,4 +1,4 @@ -package com.arup.cml.kpi; +package com.arup.cml.abm.kpi; import tech.tablesaw.api.StringColumn; import tech.tablesaw.api.Table; diff --git a/src/main/java/com/arup/cml/abm/kpi/KpiApi.java b/src/main/java/com/arup/cml/abm/kpi/KpiApi.java new file mode 100644 index 0000000..1bf4f6f --- /dev/null +++ b/src/main/java/com/arup/cml/abm/kpi/KpiApi.java @@ -0,0 +1,6 @@ +package com.arup.cml.abm.kpi; + +public interface KpiApi { + + +} diff --git a/src/main/java/com/arup/cml/abm/kpi/LinkLog.java b/src/main/java/com/arup/cml/abm/kpi/LinkLog.java new file mode 100644 index 0000000..c38f762 --- /dev/null +++ b/src/main/java/com/arup/cml/abm/kpi/LinkLog.java @@ -0,0 +1,4 @@ +package com.arup.cml.abm.kpi; + +public interface LinkLog { +} diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/MATSimModel.java b/src/main/java/com/arup/cml/abm/kpi/matsim/MATSimModel.java index 6295f52..f33617a 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/MATSimModel.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/MATSimModel.java @@ -1,7 +1,7 @@ -package com.arup.cml.kpi.matsim; +package com.arup.cml.abm.kpi.matsim; -import com.arup.cml.kpi.DataModel; -import com.arup.cml.kpi.matsim.handlers.LinkLogHandler; +import com.arup.cml.abm.kpi.matsim.handlers.LinkLogHandler; +import com.arup.cml.abm.kpi.DataModel; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Scenario; diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/LinkLogHandler.java b/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/LinkLogHandler.java index 9234488..5d71854 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/LinkLogHandler.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/LinkLogHandler.java @@ -1,4 +1,4 @@ -package com.arup.cml.kpi.matsim.handlers; +package com.arup.cml.abm.kpi.matsim.handlers; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.*; diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/run/KpiGenerator.java b/src/main/java/com/arup/cml/abm/kpi/matsim/run/KpiGenerator.java index 021a40e..1a40abd 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/run/KpiGenerator.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/run/KpiGenerator.java @@ -1,10 +1,11 @@ -package com.arup.cml.kpi.matsim.run; +package com.arup.cml.abm.kpi.matsim.run; -import com.arup.cml.kpi.KPIDomainModel; +import com.arup.cml.abm.kpi.KPIDomainModel; +import com.arup.cml.abm.kpi.matsim.MATSimModel; import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; -import com.arup.cml.kpi.matsim.MATSimModel; + import java.io.File; @Command(name = "KpiGenerator", version = "1.0-SNAPSHOT", mixinStandardHelpOptions = true) diff --git a/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiApi.java b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiApi.java new file mode 100644 index 0000000..826d5e5 --- /dev/null +++ b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiApi.java @@ -0,0 +1,6 @@ +package com.arup.cml.abm.kpi.tablesaw; + +import com.arup.cml.abm.kpi.KpiApi; + +public class TablesawKpiApi implements KpiApi { +} diff --git a/src/test/java/com/arup/cml/abm/kpi/TableHelpers.java b/src/test/java/com/arup/cml/abm/kpi/TableHelpers.java index 7576f42..af67749 100644 --- a/src/test/java/com/arup/cml/abm/kpi/TableHelpers.java +++ b/src/test/java/com/arup/cml/abm/kpi/TableHelpers.java @@ -1,4 +1,4 @@ -package com.arup.cml.kpi; +package com.arup.cml.abm.kpi; import tech.tablesaw.api.Table; import tech.tablesaw.columns.Column; diff --git a/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java b/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java new file mode 100644 index 0000000..5407725 --- /dev/null +++ b/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java @@ -0,0 +1,48 @@ +package com.arup.cml.abm.kpi.integration; + +import com.arup.cml.abm.kpi.matsim.run.KpiGenerator; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import picocli.CommandLine; + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +public class KpiGeneratorIntegrationTest { + + @Rule + public TemporaryFolder appOutputDir = new TemporaryFolder(); + + @Test + public void testApp() throws Exception { + CommandLine cmd = new CommandLine(new KpiGenerator()); + cmd.setOut(new PrintWriter(new StringWriter())); + Path resourceDirectory = Paths.get("src","test","resources"); + + int exitCode = cmd.execute( + "-mc", + String.format("%s/integration-test-data/smol-matsim-outputs/output_config.xml", resourceDirectory), + "-mo", + String.format("%s/integration-test-data/smol-matsim-outputs", resourceDirectory), + "-o", + appOutputDir.getRoot().getAbsolutePath() + ); + + assertThat(exitCode).isEqualTo(0).as("App return code should be zero"); + String[] outputFilesList = appOutputDir.getRoot().list(); + assertThat(outputFilesList).hasSize(6).as("Check number of output files created"); + assertThat(outputFilesList).contains("kpi.csv").as("Check KPI CSV file exists"); + File expectedKpiFile = + new File(String.format("%s/integration-test-data/smol-matsim-outputs/expected-kpi.csv", + resourceDirectory)); + assertThat(new File(String.format("%s/kpi.csv", appOutputDir.getRoot()))) + .hasSameTextualContentAs(expectedKpiFile) + .as("Check KPI data"); + } +} diff --git a/src/test/java/com/arup/cml/abm/kpi/matsim/TestNothing.java b/src/test/java/com/arup/cml/abm/kpi/matsim/TestNothing.java index 9c5292c..5e5ed5c 100644 --- a/src/test/java/com/arup/cml/abm/kpi/matsim/TestNothing.java +++ b/src/test/java/com/arup/cml/abm/kpi/matsim/TestNothing.java @@ -1,4 +1,4 @@ -package com.arup.cml.kpi.matsim; +package com.arup.cml.abm.kpi.matsim; import org.junit.Test; diff --git a/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandler.java b/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandler.java index d58e09e..578fc0b 100644 --- a/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandler.java +++ b/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandler.java @@ -1,4 +1,4 @@ -package com.arup.cml.kpi.matsim.handlers; +package com.arup.cml.abm.kpi.matsim.handlers; import org.junit.Test; import org.matsim.api.core.v01.Id; diff --git a/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandlerWithMultipleAgents.java b/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandlerWithMultipleAgents.java index 771666b..551716c 100644 --- a/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandlerWithMultipleAgents.java +++ b/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandlerWithMultipleAgents.java @@ -1,6 +1,6 @@ -package com.arup.cml.kpi.matsim.handlers; +package com.arup.cml.abm.kpi.matsim.handlers; -import com.arup.cml.kpi.TableHelpers; +import com.arup.cml.abm.kpi.TableHelpers; import org.junit.Before; import org.junit.Test; import org.matsim.api.core.v01.Id; diff --git a/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandlerWithSimpleData.java b/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandlerWithSimpleData.java index 0d5d04b..1a8f55e 100644 --- a/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandlerWithSimpleData.java +++ b/src/test/java/com/arup/cml/abm/kpi/matsim/handlers/TestLinkLogHandlerWithSimpleData.java @@ -1,6 +1,6 @@ -package com.arup.cml.kpi.matsim.handlers; +package com.arup.cml.abm.kpi.matsim.handlers; -import com.arup.cml.kpi.TableHelpers; +import com.arup.cml.abm.kpi.TableHelpers; import org.junit.Before; import org.junit.Test; import org.matsim.api.core.v01.Id; diff --git a/src/test/regression/data/smol-matsim-outputs/output_config_reduced.xml b/src/test/regression/data/smol-matsim-outputs/output_config_reduced.xml deleted file mode 100644 index dee0eda..0000000 --- a/src/test/regression/data/smol-matsim-outputs/output_config_reduced.xml +++ /dev/null @@ -1,589 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/regression/data/smol-matsim-outputs/output_counts.xml.gz b/src/test/regression/data/smol-matsim-outputs/output_counts.xml.gz deleted file mode 100644 index d0ba19fcf74ff99b1b7128486fda5b8a2b9fa9d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 194 zcmV;z06qU7iwFP!000000IiO}4uUWcMDP8Ib?>F17egrCJfRmg@n)J*v5DOpwgUdW zMEwNkI+ORN+DzdNgX`Hx(pY3Uf+HJSPo2ioaVyujsYPYulM=%`CN3xT8gD5*N~Oke z%*Is~`%W$Myin&|bFeoTjP%6GkaZ~LeMxa|g5!s=?%Oxfn)H$WNWmob;X}ImyJOX+ wR(-vfp~xm~Q2@;ljR-GidX4j0s6kWaNjn>st-hAEwjQ zbeG`1hwB4$*ZL2f^N#ibb<^l^JdIP2O8R+7Z>?T88szEuX6Rog4X^ranya>d_5E9O z9?S@6PZY>O@k$8-geY=Ul%eB(K}u_ydH`B*DD2G-0tLg1C?tpy-3qPyLFAgxfR>6% zB}#{-L`kvm%gE1YxnRQoSx@>_gTJ^4DrH3&g1J=kuqe=jHBaWE;aF6TjYPQ(fzA>h zy4A2z92B#3i>8Vn72}JBm^CtDE}CjQ>tT2RT3-i-ycxVWwtub{Op2!$V$PCuj*RF( zL77mLhbj>2i+i6o5Ep_Za;e0*ziHoKwvXVgA13JUhd`UVHvQx#5? zNK(UGRWK=T(hf4I_5Rr%GNq?yr*8eFbUD*=Sf;nohu*fnGpn;xS5_f5dB?RuMPciG z2#Yn_ugmEjH09%R4X0;{SU+9f)y`V-tUbYn|EoXO9ia7{BW2P#NCcs`@q(5njw& z1F36?brc^;WVk)eM55JK^QvvVqZ4*|tOymWbXDmr%aloZK}CEQiKQTsyC=o)yFn}n z<%%5>DH4mnL#~QroQ}^3@l}`Em{=N98H6^_EX2R52>hb(C7F{r_+OB@65kj9H*>!M LBXdlK&I$kk-56!w diff --git a/src/test/regression/data/smol-matsim-outputs/output_persons.csv.gz b/src/test/regression/data/smol-matsim-outputs/output_persons.csv.gz deleted file mode 100644 index 00cf00050d130db6c54f4e73c918cfd4c79e6afe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 336 zcmV-W0k8faiwFP!000000DY0&Zo?o9M(->29rgl^3gm=88Rz#t^>bTJF?IW0 z)eLbIg}P8^to4RSS>xqk0Sb_VUXCVRf;92myv44{^?r9Mr*J7n0T!Tv5lDd{i%LAK zq@p8A{OMpI!}m78%J4wrR+w=vJF?se%TUpJn{@qvl6oZ{Whc=j`BQndzBM0duuS? zEYFSJ4EK?mvRgbA8Ft<~2IEi*@ruGG`dN-KFGF!*9C)uiDrRlH82_vKr)wSB_!aKH iz5ol}YHUxgj!JyV%7FKs^* z^~q>+KUKCgMLlob3R~y5rZl>0>Wk@z=SP0m4ZVh)Zpe$%VBhTU$cIM@Usji^9e>xk zIN8eWfj+-e+4?#z-^clZkB7IqYrN4d-f?{Bv+Y1pJLE4-(UrEoROgdA#Y{2Am@u4c2kmOUUID+|7RP2Ki|4~$JPgfA-CLby>i2{Kn zI1(atL!8EkM)+8{aS@UfW)vKj?T{*9%2}z81Z8y&h+u zYx1mZIMp<$ZSLAFmHdO+rX->iZHnNwtKf~VC_X=^S2-u~m?3=+V zpO$0GpK?ycBJimTd=iUv4m|uwYINB(ZF4@u!_W31H|{BqsF>b3LT*H`Sp>u17gN$H zS1b!e5MT7cdw%9mD|XDp57H=`4*XgNpLOuX0f1nzFc>iggUYQA_FVB@+i0 t@TbQYGV( - diff --git a/src/test/regression/data/smol-matsim-outputs/output_events.xml.gz b/src/test/resources/integration-test-data/smol-matsim-outputs/output_events.xml.gz similarity index 100% rename from src/test/regression/data/smol-matsim-outputs/output_events.xml.gz rename to src/test/resources/integration-test-data/smol-matsim-outputs/output_events.xml.gz diff --git a/src/test/regression/data/smol-matsim-outputs/output_facilities.xml.gz b/src/test/resources/integration-test-data/smol-matsim-outputs/output_facilities.xml.gz similarity index 100% rename from src/test/regression/data/smol-matsim-outputs/output_facilities.xml.gz rename to src/test/resources/integration-test-data/smol-matsim-outputs/output_facilities.xml.gz diff --git a/src/test/regression/data/smol-matsim-outputs/output_households.xml.gz b/src/test/resources/integration-test-data/smol-matsim-outputs/output_households.xml.gz similarity index 100% rename from src/test/regression/data/smol-matsim-outputs/output_households.xml.gz rename to src/test/resources/integration-test-data/smol-matsim-outputs/output_households.xml.gz diff --git a/src/test/regression/data/smol-matsim-outputs/output_network.xml.gz b/src/test/resources/integration-test-data/smol-matsim-outputs/output_network.xml.gz similarity index 100% rename from src/test/regression/data/smol-matsim-outputs/output_network.xml.gz rename to src/test/resources/integration-test-data/smol-matsim-outputs/output_network.xml.gz diff --git a/src/test/regression/data/smol-matsim-outputs/output_plans.xml.gz b/src/test/resources/integration-test-data/smol-matsim-outputs/output_plans.xml.gz similarity index 100% rename from src/test/regression/data/smol-matsim-outputs/output_plans.xml.gz rename to src/test/resources/integration-test-data/smol-matsim-outputs/output_plans.xml.gz diff --git a/src/test/regression/data/smol-matsim-outputs/output_transitSchedule.xml.gz b/src/test/resources/integration-test-data/smol-matsim-outputs/output_transitSchedule.xml.gz similarity index 100% rename from src/test/regression/data/smol-matsim-outputs/output_transitSchedule.xml.gz rename to src/test/resources/integration-test-data/smol-matsim-outputs/output_transitSchedule.xml.gz diff --git a/src/test/regression/data/smol-matsim-outputs/output_transitVehicles.xml.gz b/src/test/resources/integration-test-data/smol-matsim-outputs/output_transitVehicles.xml.gz similarity index 100% rename from src/test/regression/data/smol-matsim-outputs/output_transitVehicles.xml.gz rename to src/test/resources/integration-test-data/smol-matsim-outputs/output_transitVehicles.xml.gz diff --git a/src/test/regression/data/smol-matsim-outputs/output_vehicles.xml.gz b/src/test/resources/integration-test-data/smol-matsim-outputs/output_vehicles.xml.gz similarity index 100% rename from src/test/regression/data/smol-matsim-outputs/output_vehicles.xml.gz rename to src/test/resources/integration-test-data/smol-matsim-outputs/output_vehicles.xml.gz From ef465601575dbcba203f6ab9db10734ddcdc20eb Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Tue, 23 Jan 2024 03:41:49 +0000 Subject: [PATCH 03/16] Remove the dummy unit test --- .../com/arup/cml/abm/kpi/matsim/TestNothing.java | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 src/test/java/com/arup/cml/abm/kpi/matsim/TestNothing.java diff --git a/src/test/java/com/arup/cml/abm/kpi/matsim/TestNothing.java b/src/test/java/com/arup/cml/abm/kpi/matsim/TestNothing.java deleted file mode 100644 index 5e5ed5c..0000000 --- a/src/test/java/com/arup/cml/abm/kpi/matsim/TestNothing.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.arup.cml.abm.kpi.matsim; - - -import org.junit.Test; - - -import static org.assertj.core.api.Assertions.assertThat; - -public class TestNothing { - - @Test - public void testNothing() { - assertThat(true).isEqualTo(true); - } -} From f38f41ac5f8382e8c1368c906773491d5eff8367 Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Tue, 23 Jan 2024 03:52:54 +0000 Subject: [PATCH 04/16] Improve an integration test assertion description --- .../cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java b/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java index 5407725..22f0e1d 100644 --- a/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java +++ b/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java @@ -43,6 +43,6 @@ public void testApp() throws Exception { resourceDirectory)); assertThat(new File(String.format("%s/kpi.csv", appOutputDir.getRoot()))) .hasSameTextualContentAs(expectedKpiFile) - .as("Check KPI data"); + .as("Check calculated KPI data"); } } From 577b979a9522e3d27a4fc8b5dc3f5df8839d4253 Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Tue, 23 Jan 2024 04:14:17 +0000 Subject: [PATCH 05/16] Make some KPI generator args mandatory --- .../arup/cml/abm/kpi/matsim/run/KpiGenerator.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/run/KpiGenerator.java b/src/main/java/com/arup/cml/abm/kpi/matsim/run/KpiGenerator.java index 1a40abd..e5610eb 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/run/KpiGenerator.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/run/KpiGenerator.java @@ -6,25 +6,17 @@ import picocli.CommandLine.Command; import picocli.CommandLine.Option; -import java.io.File; - @Command(name = "KpiGenerator", version = "1.0-SNAPSHOT", mixinStandardHelpOptions = true) public class KpiGenerator implements Runnable { - - @Option(names = "-c", description = "Sets the check configuration file to use.") - private File configurationFile; - - @Option(names = "-mc", description = "Sets the MATSim config file to use.") + @Option(names = "-mc", description = "Sets the MATSim config file to use.", required = true) private String matsimConfigFile; - @Option(names = "-mo", description = "Sets the MATSim output directory use.") + @Option(names = "-mo", description = "Sets the MATSim output directory use.", required = true) private String matsimOutputDirectory; - @Option(names = "-o", description = "Sets the output directory. Defaults to stdout") + @Option(names = "-o", description = "Sets the output directory. Defaults to stdout", required = true) private String outputDir; - @Option(names = "-v", versionHelp = true, description = "Print product version and exit") - private boolean versionHelpRequested; public static void main(String[] args) { int exitCode = new CommandLine(new KpiGenerator()).execute(args); System.exit(exitCode); From 999f25753396f1b190e2f13a0b805b3a15dff2ec Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Tue, 23 Jan 2024 04:22:23 +0000 Subject: [PATCH 06/16] Clean up the integration test a little --- .../abm/kpi/integration/KpiGeneratorIntegrationTest.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java b/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java index 22f0e1d..5a4d640 100644 --- a/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java +++ b/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java @@ -24,12 +24,13 @@ public void testApp() throws Exception { CommandLine cmd = new CommandLine(new KpiGenerator()); cmd.setOut(new PrintWriter(new StringWriter())); Path resourceDirectory = Paths.get("src","test","resources"); + String testDataDirRoot = String.format("%s/integration-test-data/smol-matsim-outputs/", resourceDirectory); int exitCode = cmd.execute( "-mc", - String.format("%s/integration-test-data/smol-matsim-outputs/output_config.xml", resourceDirectory), + String.format("%s/output_config.xml", testDataDirRoot), "-mo", - String.format("%s/integration-test-data/smol-matsim-outputs", resourceDirectory), + testDataDirRoot, "-o", appOutputDir.getRoot().getAbsolutePath() ); @@ -38,9 +39,7 @@ public void testApp() throws Exception { String[] outputFilesList = appOutputDir.getRoot().list(); assertThat(outputFilesList).hasSize(6).as("Check number of output files created"); assertThat(outputFilesList).contains("kpi.csv").as("Check KPI CSV file exists"); - File expectedKpiFile = - new File(String.format("%s/integration-test-data/smol-matsim-outputs/expected-kpi.csv", - resourceDirectory)); + File expectedKpiFile = new File(String.format("%s/expected-kpi.csv", testDataDirRoot)); assertThat(new File(String.format("%s/kpi.csv", appOutputDir.getRoot()))) .hasSameTextualContentAs(expectedKpiFile) .as("Check calculated KPI data"); From f0e7ad30e8faec709ff603013e6a0dff5dac1de9 Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Tue, 23 Jan 2024 14:16:05 +0000 Subject: [PATCH 07/16] Simplify the integration test --- .../kpi/integration/KpiGeneratorIntegrationTest.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java b/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java index 5a4d640..4029853 100644 --- a/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java +++ b/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java @@ -7,9 +7,6 @@ import picocli.CommandLine; import java.io.File; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.nio.file.Path; import java.nio.file.Paths; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; @@ -21,12 +18,10 @@ public class KpiGeneratorIntegrationTest { @Test public void testApp() throws Exception { - CommandLine cmd = new CommandLine(new KpiGenerator()); - cmd.setOut(new PrintWriter(new StringWriter())); - Path resourceDirectory = Paths.get("src","test","resources"); - String testDataDirRoot = String.format("%s/integration-test-data/smol-matsim-outputs/", resourceDirectory); + String testDataDirRoot = String.format("%s/integration-test-data/smol-matsim-outputs/", + Paths.get("src","test","resources")); - int exitCode = cmd.execute( + int exitCode = new CommandLine(new KpiGenerator()).execute( "-mc", String.format("%s/output_config.xml", testDataDirRoot), "-mo", From 9e4a6f3e92c1938867e22bd235ef7369974d703c Mon Sep 17 00:00:00 2001 From: "kasia.kozlowska" Date: Tue, 23 Jan 2024 15:28:28 +0000 Subject: [PATCH 08/16] fix congestion --- .../java/com/arup/cml/abm/kpi/KPIDomainModel.java | 14 +++++--------- .../smol-matsim-outputs/expected-kpi.csv | 4 +++- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java b/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java index 5f5550c..8dcef65 100644 --- a/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java +++ b/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java @@ -1,5 +1,6 @@ package com.arup.cml.abm.kpi; +import tech.tablesaw.api.IntColumn; import tech.tablesaw.api.StringColumn; import tech.tablesaw.api.Table; @@ -47,10 +48,10 @@ public Table congestion() { ); // put in hour bins - StringColumn hour = StringColumn.create("hour"); + IntColumn hour = IntColumn.create("hour"); linkLog.doubleColumn("endTime") .forEach(time -> hour.append( - String.valueOf((int) Math.floor(time / (60 * 60))) + (int) Math.floor(time / (60 * 60)) )); linkLog.addColumns(hour); @@ -61,16 +62,11 @@ public Table congestion() { .by("linkID", "mode", "hour"); intermediate.write().csv(String.format("%s/congestion.csv", outputDir)); - linkLog.where( - linkLog.stringColumn("hour").asDoubleColumn().isGreaterThanOrEqualTo(7) - .and(linkLog.stringColumn("hour").asDoubleColumn().isLessThanOrEqualTo(9)) - ); - // kpi output Table kpi = linkLog - .where(linkLog.stringColumn("hour").asDoubleColumn().isGreaterThanOrEqualTo(7) - .and(linkLog.stringColumn("hour").asDoubleColumn().isLessThanOrEqualTo(9))) + .where(linkLog.intColumn("hour").isGreaterThanOrEqualTo(7) + .and(linkLog.intColumn("hour").isLessThanOrEqualTo(9))) .summarize("delayRatio", mean) .by("mode") .setName("Congestion KPI"); diff --git a/src/test/resources/integration-test-data/smol-matsim-outputs/expected-kpi.csv b/src/test/resources/integration-test-data/smol-matsim-outputs/expected-kpi.csv index 8376a19..3cf8111 100644 --- a/src/test/resources/integration-test-data/smol-matsim-outputs/expected-kpi.csv +++ b/src/test/resources/integration-test-data/smol-matsim-outputs/expected-kpi.csv @@ -1,2 +1,4 @@ mode,Mean [delayRatio] -bike,12.68 \ No newline at end of file +car,1.3187068645640074 +walk,6.54 +bike,10.093055555555555 \ No newline at end of file From 719fb53381097a85f69d30b38dc3b8da7763257c Mon Sep 17 00:00:00 2001 From: "kasia.kozlowska" Date: Tue, 23 Jan 2024 15:40:35 +0000 Subject: [PATCH 09/16] remove useless import --- src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java b/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java index 8dcef65..7c5972f 100644 --- a/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java +++ b/src/main/java/com/arup/cml/abm/kpi/KPIDomainModel.java @@ -1,7 +1,6 @@ package com.arup.cml.abm.kpi; import tech.tablesaw.api.IntColumn; -import tech.tablesaw.api.StringColumn; import tech.tablesaw.api.Table; import static tech.tablesaw.aggregate.AggregateFunctions.mean; From 1e867544083bc7d6e510c940146983883068fe90 Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Wed, 24 Jan 2024 22:16:56 +0000 Subject: [PATCH 10/16] Start to separate Tablesaw-aware code from MATSim-aware code --- .../java/com/arup/cml/abm/kpi/KpiApi.java | 6 - .../com/arup/cml/abm/kpi/KpiCalculator.java | 13 ++ .../arup/cml/abm/kpi/matsim/MATSimModel.java | 5 +- .../arup/cml/abm/kpi/matsim/MatsimUtils.java | 89 ++++++++ .../kpi/matsim/handlers/LinkLogHandler.java | 18 +- .../matsim/handlers/MatsimLinkLogHandler.java | 96 ++++++++ .../kpi/matsim/run/MatsimKpiGenerator.java | 76 +++++++ .../cml/abm/kpi/tablesaw/TablesawKpiApi.java | 6 - .../kpi/tablesaw/TablesawKpiCalculator.java | 208 ++++++++++++++++++ .../KpiGeneratorIntegrationTest.java | 2 +- .../MatsimKpiGeneratorIntegrationTest.java | 42 ++++ 11 files changed, 537 insertions(+), 24 deletions(-) delete mode 100644 src/main/java/com/arup/cml/abm/kpi/KpiApi.java create mode 100644 src/main/java/com/arup/cml/abm/kpi/KpiCalculator.java create mode 100644 src/main/java/com/arup/cml/abm/kpi/matsim/MatsimUtils.java create mode 100644 src/main/java/com/arup/cml/abm/kpi/matsim/handlers/MatsimLinkLogHandler.java create mode 100644 src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java delete mode 100644 src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiApi.java create mode 100644 src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java create mode 100644 src/test/java/com/arup/cml/abm/kpi/integration/MatsimKpiGeneratorIntegrationTest.java diff --git a/src/main/java/com/arup/cml/abm/kpi/KpiApi.java b/src/main/java/com/arup/cml/abm/kpi/KpiApi.java deleted file mode 100644 index 1bf4f6f..0000000 --- a/src/main/java/com/arup/cml/abm/kpi/KpiApi.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.arup.cml.abm.kpi; - -public interface KpiApi { - - -} diff --git a/src/main/java/com/arup/cml/abm/kpi/KpiCalculator.java b/src/main/java/com/arup/cml/abm/kpi/KpiCalculator.java new file mode 100644 index 0000000..00fe36d --- /dev/null +++ b/src/main/java/com/arup/cml/abm/kpi/KpiCalculator.java @@ -0,0 +1,13 @@ +package com.arup.cml.abm.kpi; + +import java.nio.file.Path; + +public interface KpiCalculator { + + public void linkEntered(String vehicleId, String linkId, double timestamp); + public void linkExited(String vehicleId, String linkId, double timestamp); + public void vehicleEntered(String vehicleId, String personId); + public void vehicleExited(String vehicleId, String personId); + public void recordVehicleMode(String vehicleId, String mode); + public void writeCongestionKpi(Path directory); +} diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/MATSimModel.java b/src/main/java/com/arup/cml/abm/kpi/matsim/MATSimModel.java index f33617a..0cf7fe8 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/MATSimModel.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/MATSimModel.java @@ -78,10 +78,7 @@ private Config getConfig(String matsimInputConfig) { System.out.println("Config group " + module + " is read as is"); } else { ReflectiveConfigGroup relaxedModule = - new ReflectiveConfigGroup(module.getName(),true) {}; -// for (Map.Entry entry : module.getParams().entrySet()) { -// relaxedModule.addParam(entry.getKey(), entry.getValue()); -// } + new ReflectiveConfigGroup(module.getName(), true) {}; config.removeModule(module.getName()); config.addModule(relaxedModule); } diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/MatsimUtils.java b/src/main/java/com/arup/cml/abm/kpi/matsim/MatsimUtils.java new file mode 100644 index 0000000..1514aec --- /dev/null +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/MatsimUtils.java @@ -0,0 +1,89 @@ +package com.arup.cml.abm.kpi.matsim; + +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.network.Network; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigGroup; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.config.ReflectiveConfigGroup; +import org.matsim.core.config.groups.*; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.pt.config.TransitConfigGroup; + +import java.nio.file.Path; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.TreeMap; + +public class MatsimUtils { + + private Path matsimOutputDir; + private Network matsimNetwork; + private Config matsimConfig; + private Scenario matsimScenario; + + public MatsimUtils(Path matsimOutputDir, Path matsimConfigFile) { + this.matsimOutputDir = matsimOutputDir; + this.matsimConfig = getConfig(matsimConfigFile.toString()); + this.matsimScenario = ScenarioUtils.loadScenario(matsimConfig); + this.matsimNetwork = matsimScenario.getNetwork(); + } + + private final Set necessaryConfigGroups = new HashSet<>(Arrays.asList( + GlobalConfigGroup.GROUP_NAME, + PlansConfigGroup.GROUP_NAME, + FacilitiesConfigGroup.GROUP_NAME, + HouseholdsConfigGroup.GROUP_NAME, + TransitConfigGroup.GROUP_NAME, + VehiclesConfigGroup.GROUP_NAME, + NetworkConfigGroup.GROUP_NAME + )); + + public Config getConfig(String matsimInputConfig) { + Config config = ConfigUtils.createConfig(); + TreeMap configuredModules = config.getModules(); + for (ConfigGroup module : configuredModules.values().stream().toList()) { + if (necessaryConfigGroups.contains(module.getName())) { + System.out.println("Config group " + module + " is read as is"); + } else { + ReflectiveConfigGroup relaxedModule = + new ReflectiveConfigGroup(module.getName(), true) {}; + config.removeModule(module.getName()); + config.addModule(relaxedModule); + } + } + ConfigUtils.loadConfig(config, String.format(matsimInputConfig)); + setOutputFilePaths(config); + return config; + } + + private void setOutputFilePaths(Config config) { + TreeMap modules = config.getModules(); + modules.get("network") + .addParam("inputNetworkFile", + String.format("%s/output_network.xml.gz", this.matsimOutputDir)); + modules.get("transit") + .addParam("transitScheduleFile", + String.format("%s/output_transitSchedule.xml.gz", this.matsimOutputDir)); + modules.get("transit") + .addParam("vehiclesFile", + String.format("%s/output_transitVehicles.xml.gz", this.matsimOutputDir)); + modules.get("plans") + .addParam("inputPlansFile", + String.format("%s/output_plans.xml.gz", this.matsimOutputDir)); + modules.get("households") + .addParam("inputFile", + String.format("%s/output_households.xml.gz", this.matsimOutputDir)); + modules.get("facilities") + .addParam("inputFacilitiesFile", + String.format("%s/output_facilities.xml.gz", this.matsimOutputDir)); + modules.get("vehicles") + .addParam("vehiclesFile", + String.format("%s/output_vehicles.xml.gz", this.matsimOutputDir)); + } + + public Network getMatsimNetwork() { + return matsimNetwork; + } +} diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/LinkLogHandler.java b/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/LinkLogHandler.java index 5d71854..90ea177 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/LinkLogHandler.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/LinkLogHandler.java @@ -11,9 +11,13 @@ import java.util.*; import java.util.stream.LongStream; -public class LinkLogHandler implements VehicleEntersTrafficEventHandler, VehicleLeavesTrafficEventHandler, - PersonEntersVehicleEventHandler, PersonLeavesVehicleEventHandler, - LinkEnterEventHandler, LinkLeaveEventHandler { +public class LinkLogHandler implements + VehicleEntersTrafficEventHandler, + VehicleLeavesTrafficEventHandler, + PersonEntersVehicleEventHandler, + PersonLeavesVehicleEventHandler, + LinkEnterEventHandler, + LinkLeaveEventHandler { // arrays to collect Link Log data, each will form a column of the Link Log private final ArrayList vehicleIDColumn = new ArrayList<>(); @@ -91,10 +95,10 @@ public Table getVehicleOccupancy() { ); } - public void write(String outputDir) { - getLinkLog().write().csv(String.format("%s/linkLog.csv", outputDir)); - getVehicleOccupancy().write().csv(String.format("%s/vehicleOccupancy.csv", outputDir)); - } +// public void write(String outputDir) { +// getLinkLog().write().csv(String.format("%s/linkLog.csv", outputDir)); +// getVehicleOccupancy().write().csv(String.format("%s/vehicleOccupancy.csv", outputDir)); +// } @Override public void handleEvent(VehicleEntersTrafficEvent event) { diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/MatsimLinkLogHandler.java b/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/MatsimLinkLogHandler.java new file mode 100644 index 0000000..550ec68 --- /dev/null +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/MatsimLinkLogHandler.java @@ -0,0 +1,96 @@ +package com.arup.cml.abm.kpi.matsim.handlers; + +import com.arup.cml.abm.kpi.KpiCalculator; +import org.matsim.api.core.v01.events.*; +import org.matsim.api.core.v01.events.handler.*; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +public class MatsimLinkLogHandler implements + VehicleEntersTrafficEventHandler, + VehicleLeavesTrafficEventHandler, + PersonEntersVehicleEventHandler, + PersonLeavesVehicleEventHandler, + LinkEnterEventHandler, + LinkLeaveEventHandler { + + private KpiCalculator kpiCalculator; + private int eventCount; + private Map eventCounts = new HashMap<>(); + + public MatsimLinkLogHandler(KpiCalculator kpiCalculator) { + this.kpiCalculator = kpiCalculator; + } + + @Override + public void handleEvent(LinkEnterEvent event) { + incrementEventCount(event); + kpiCalculator.linkEntered( + event.getVehicleId().toString(), + event.getLinkId().toString(), + event.getTime() + ); + } + + @Override + public void handleEvent(LinkLeaveEvent event) { + incrementEventCount(event); + kpiCalculator.linkExited( + event.getVehicleId().toString(), + event.getLinkId().toString(), + event.getTime() + ); + } + + @Override + public void handleEvent(PersonEntersVehicleEvent event) { + incrementEventCount(event); + kpiCalculator.vehicleEntered( + event.getVehicleId().toString(), + event.getPersonId().toString() + ); + } + + @Override + public void handleEvent(PersonLeavesVehicleEvent event) { + incrementEventCount(event); + kpiCalculator.vehicleExited( + event.getVehicleId().toString(), + event.getPersonId().toString() + ); + } + + @Override + public void handleEvent(VehicleEntersTrafficEvent event) { + incrementEventCount(event); + // this is the earliest event we will see for this vehicle, and includes the + // mode, which is missing from subsequent link events, so we must grab it now + kpiCalculator.recordVehicleMode(event.getVehicleId().toString(), event.getNetworkMode()); + kpiCalculator.linkEntered( + event.getVehicleId().toString(), + event.getLinkId().toString(), + event.getTime() + ); + } + + @Override + public void handleEvent(VehicleLeavesTrafficEvent event) { + incrementEventCount(event); + kpiCalculator.linkExited( + event.getVehicleId().toString(), + event.getLinkId().toString(), + event.getTime() + ); + } + + public Map getEventCounts() { + return this.eventCounts; + } + + private void incrementEventCount(Event e) { + this.eventCounts.putIfAbsent(e.getEventType(), new AtomicInteger(0)); + this.eventCounts.get(e.getEventType()).incrementAndGet(); + } +} diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java b/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java new file mode 100644 index 0000000..ad5f34a --- /dev/null +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java @@ -0,0 +1,76 @@ +package com.arup.cml.abm.kpi.matsim.run; + +import com.arup.cml.abm.kpi.KPIDomainModel; +import com.arup.cml.abm.kpi.KpiCalculator; +import com.arup.cml.abm.kpi.matsim.MATSimModel; +import com.arup.cml.abm.kpi.matsim.MatsimUtils; +import com.arup.cml.abm.kpi.matsim.handlers.LinkLogHandler; +import com.arup.cml.abm.kpi.matsim.handlers.MatsimLinkLogHandler; +import com.arup.cml.abm.kpi.tablesaw.TablesawKpiCalculator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.events.EventsUtils; +import org.matsim.core.events.MatsimEventsReader; +import picocli.CommandLine; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; + +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import static java.lang.String.format; + +@Command(name = "MatsimKpiGenerator", version = "1.0-SNAPSHOT", mixinStandardHelpOptions = true) +public class MatsimKpiGenerator implements Runnable { + @Option(names = "-mc", description = "Sets the MATSim config file to use.", required = true) + private Path matsimConfigFile; + + @Option(names = "-mo", description = "Sets the MATSim output directory use.", required = true) + private Path matsimOutputDirectory; + + @Option(names = "-o", description = "Sets the output directory. Defaults to stdout", required = true) + private String outputDir; + + public static void main(String[] args) { + int exitCode = new CommandLine(new MatsimKpiGenerator()).execute(args); + System.exit(exitCode); + } + + @Override + public void run() { + System.out.printf("Writing KPI metrics to %s, generated from MATSim outputs at %s, using MATSim config %s%n", + outputDir, + matsimOutputDirectory, + matsimConfigFile); + + MatsimUtils matsimUtils = new MatsimUtils(matsimOutputDirectory, matsimConfigFile); + KpiCalculator kpiCalculator = new TablesawKpiCalculator(matsimUtils.getMatsimNetwork()); + MatsimLinkLogHandler matsimLinkLogHandler = new MatsimLinkLogHandler(kpiCalculator); + EventsManager eventsManager = EventsUtils.createEventsManager(); + eventsManager.addHandler(matsimLinkLogHandler); + + String outputEventsFile = String.format("%s/output_events.xml.gz", matsimOutputDirectory); + System.out.printf("Streaming MATSim events from %s%n", outputEventsFile); + new MatsimEventsReader(eventsManager).readFile(outputEventsFile); + Map eventsSeen = matsimLinkLogHandler.getEventCounts(); + Integer eventCount = eventsSeen.values() + .stream() + .mapToInt(AtomicInteger::intValue) + .sum(); + System.out.printf("Recorded %,d relevant MATSim events from %s%n", eventCount, outputEventsFile); + try { + System.out.println(new ObjectMapper(). + writerWithDefaultPrettyPrinter(). + writeValueAsString(eventsSeen)); + } catch (JsonProcessingException e) { + // swallow + } + + // get the network link info from the matsim outputs and pass it into the calculator + + kpiCalculator.writeCongestionKpi(Path.of(format("%s/congestion-kpi.csv", outputDir))); + } +} diff --git a/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiApi.java b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiApi.java deleted file mode 100644 index 826d5e5..0000000 --- a/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiApi.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.arup.cml.abm.kpi.tablesaw; - -import com.arup.cml.abm.kpi.KpiApi; - -public class TablesawKpiApi implements KpiApi { -} diff --git a/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java new file mode 100644 index 0000000..c2fb9b4 --- /dev/null +++ b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java @@ -0,0 +1,208 @@ +package com.arup.cml.abm.kpi.tablesaw; + +import com.arup.cml.abm.kpi.KpiCalculator; +import com.arup.cml.abm.kpi.matsim.MATSimModel; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.api.core.v01.network.Network; +import tech.tablesaw.api.DoubleColumn; +import tech.tablesaw.api.LongColumn; +import tech.tablesaw.api.StringColumn; +import tech.tablesaw.api.Table; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.stream.LongStream; + +public class TablesawKpiCalculator implements KpiCalculator { + + private static final Logger LOGGER = LogManager.getLogger(TablesawKpiCalculator.class); + + private Map vehicleModes = new HashMap<>(); + + // arrays to collect Link Log data, each will form a column of the Link Log + private final ArrayList vehicleIDColumn = new ArrayList<>(); + private final ArrayList linkIDColumn = new ArrayList<>(); + private final LinkedHashMap modeColumn = new LinkedHashMap<>(); + private final ArrayList startTimeColumn = new ArrayList<>(); + private final LinkedHashMap endTimeColumn = new LinkedHashMap<>(); + private final LinkedHashMap numberOfPeopleColumn = new LinkedHashMap<>(); + + // points to the index of the most recent reference of that vehicle ID in the Link Log + private final Map vehicleLatestLogIndex = new HashMap<>(); + + // arrays to collect agent IDs that are inside the vehicle in reference to the Link Log entries + // these will form columns of the Vehicle Occupancy table, it shows who is in the vehicle at a point in the Link Log + private final ArrayList linkLogIndexColumn = new ArrayList<>(); + private final ArrayList agentIDColumn = new ArrayList<>(); + + // tracks the most recent occupants of a vehicle + // TODO: 24/01/2024 should this be a set? + private final Map> vehicleLatestOccupants = new HashMap<>(); + + // Link Log entry index + private long index = 0; + + // TODO: 24/01/2024 replace this ASAP with a representation of the network + // that isn't from the MATSim API (a map, or dedicated domain object, or whatever) + private Network network; + + private Table networkLinks; + private Table networkLinkModes; + + public TablesawKpiCalculator(Network network) { + this.network = network; + } + + @Override + public void linkEntered(String vehicleId, String linkId, double timestamp) { + newLinkLogEntry( + vehicleId, + linkId, + vehicleModes.getOrDefault(vehicleId, "unknown"), + timestamp + ); + } + + @Override + public void linkExited(String vehicleId, String linkId, double timestamp) { + updateLinkLogEntry(vehicleId, timestamp); + } + + @Override + public void vehicleEntered(String vehicleId, String personId) { + if (vehicleLatestOccupants.containsKey(vehicleId)) { + vehicleLatestOccupants.get(vehicleId).add(personId); + } else { + ArrayList latestOccupants = new ArrayList<>(); + latestOccupants.add(personId); + vehicleLatestOccupants.put(vehicleId, latestOccupants); + } + } + + @Override + public void vehicleExited(String vehicleId, String personId) { + vehicleLatestOccupants.get(vehicleId).remove(personId); + } + + @Override + public void recordVehicleMode(String vehicleId, String mode) { + this.vehicleModes.put(vehicleId, mode); + } + + @Override + public void writeCongestionKpi(Path directory) { + System.out.printf("Writing Congestion KPIs to %s", directory); + } + + private void newLinkLogEntry(String vehicleID, String linkID, String mode, double startTime) { + vehicleIDColumn.add(vehicleID); + linkIDColumn.add(linkID.toString()); + modeColumn.put(index, mode); + startTimeColumn.add(startTime); + // end time is not known yet, a placeholder in the ordered list is saved + endTimeColumn.put(index, -1.0); + // placeholder for people in the vehicle as well - someone might enter the vehicle before it leaves the link + numberOfPeopleColumn.put(index, -1); + vehicleLatestLogIndex.put(vehicleID, index); + index++; + } + + private void newVehicleOccupantsEntry(String vehicleID, long idx) { + ArrayList currentOccupants = vehicleLatestOccupants.get(vehicleID); + for (String personID : currentOccupants) { + linkLogIndexColumn.add(idx); + agentIDColumn.add(personID.toString()); + } + } + + private void updateLinkLogEntry(String vehicleID, double endTime) { + long latestStateIndex = this.vehicleLatestLogIndex.get(vehicleID); + // update end time + endTimeColumn.put(latestStateIndex, endTime); + // update vehicle occupants + ArrayList currentOccupants = vehicleLatestOccupants.get(vehicleID); + numberOfPeopleColumn.put(latestStateIndex, currentOccupants.size()); + newVehicleOccupantsEntry(vehicleID, latestStateIndex); + } + + private Table getLinkLog() { + return Table.create("Link Log") + .addColumns( + LongColumn.create("index", LongStream.range(0, index).toArray()), + StringColumn.create("linkID", linkIDColumn), + StringColumn.create("vehicleID", vehicleIDColumn), + StringColumn.create("mode", modeColumn.values()), + DoubleColumn.create("startTime", startTimeColumn), + DoubleColumn.create("endTime", endTimeColumn.values()), + DoubleColumn.create("numberOfPeople", numberOfPeopleColumn.values()) + ); + } + + private Table getVehicleOccupancy() { + return Table.create("Vehicle Occupancy") + .addColumns( + // TODO: This should be LongColumn (reference to index LongColumn of "Link Log" table) + // but can't get it to work with LongColumn constructor as ArrayList + DoubleColumn.create("linkLogIndex", linkLogIndexColumn), + StringColumn.create("agentId", agentIDColumn) + ); + } + + private void createNetworkLinkTables(Network network) { + LOGGER.info("Creating Network Link Tables"); + + // Network Links Table Columns + StringColumn linkIDColumn = StringColumn.create("linkID"); + StringColumn fromNodeColumn = StringColumn.create("fromNode"); + StringColumn toNodeColumn = StringColumn.create("toNode"); + DoubleColumn freespeedColumn = DoubleColumn.create("freespeed"); + DoubleColumn capacityColumn = DoubleColumn.create("capacity"); + DoubleColumn lengthColumn = DoubleColumn.create("length"); + DoubleColumn lanesColumn = DoubleColumn.create("lanes"); + + // Columns for the Modes Table + // This Table supports the main Network Links Table + ArrayList modesLinkIDColumn = new ArrayList<>(); + ArrayList modesColumn = new ArrayList<>(); + + network.getLinks().forEach((id, link) -> { + String linkId = id.toString(); + + // Network Links Table data + linkIDColumn.append(linkId); + fromNodeColumn.append(link.getFromNode().getId().toString()); + toNodeColumn.append(link.getToNode().getId().toString()); + freespeedColumn.append(link.getFreespeed()); + capacityColumn.append(link.getCapacity()); + lengthColumn.append(link.getLength()); + lanesColumn.append(link.getNumberOfLanes()); + + // Modes Table data + for (String mode : link.getAllowedModes()) { + modesLinkIDColumn.add(linkId); + modesColumn.add(mode); + } + }); + + networkLinks = Table.create("Network Links") + .addColumns( + linkIDColumn, + fromNodeColumn, + toNodeColumn, + freespeedColumn, + capacityColumn, + lengthColumn, + lanesColumn + ); + + networkLinkModes = Table.create("Network Link Modes") + .addColumns( + StringColumn.create("linkID", modesLinkIDColumn), + StringColumn.create("mode", modesColumn) + ); + } +} diff --git a/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java b/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java index 4029853..cc06f6b 100644 --- a/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java +++ b/src/test/java/com/arup/cml/abm/kpi/integration/KpiGeneratorIntegrationTest.java @@ -19,7 +19,7 @@ public class KpiGeneratorIntegrationTest { @Test public void testApp() throws Exception { String testDataDirRoot = String.format("%s/integration-test-data/smol-matsim-outputs/", - Paths.get("src","test","resources")); + Paths.get("src", "test", "resources")); int exitCode = new CommandLine(new KpiGenerator()).execute( "-mc", diff --git a/src/test/java/com/arup/cml/abm/kpi/integration/MatsimKpiGeneratorIntegrationTest.java b/src/test/java/com/arup/cml/abm/kpi/integration/MatsimKpiGeneratorIntegrationTest.java new file mode 100644 index 0000000..6c687cb --- /dev/null +++ b/src/test/java/com/arup/cml/abm/kpi/integration/MatsimKpiGeneratorIntegrationTest.java @@ -0,0 +1,42 @@ +package com.arup.cml.abm.kpi.integration; + +import com.arup.cml.abm.kpi.matsim.run.MatsimKpiGenerator; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import picocli.CommandLine; + +import java.io.File; +import java.nio.file.Paths; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +public class MatsimKpiGeneratorIntegrationTest { + + @Rule + public TemporaryFolder appOutputDir = new TemporaryFolder(); + + @Test + public void testApp() throws Exception { + String testDataDirRoot = String.format("%s/integration-test-data/smol-matsim-outputs/", + Paths.get("src", "test", "resources")); + + int exitCode = new CommandLine(new MatsimKpiGenerator()).execute( + "-mc", + String.format("%s/output_config.xml", testDataDirRoot), + "-mo", + testDataDirRoot, + "-o", + appOutputDir.getRoot().getAbsolutePath() + ); + + assertThat(exitCode).isEqualTo(0).as("App return code should be zero"); +// String[] outputFilesList = appOutputDir.getRoot().list(); +// assertThat(outputFilesList).hasSize(6).as("Check number of output files created"); +// assertThat(outputFilesList).contains("kpi.csv").as("Check KPI CSV file exists"); +// File expectedKpiFile = new File(String.format("%s/expected-kpi.csv", testDataDirRoot)); +// assertThat(new File(String.format("%s/kpi.csv", appOutputDir.getRoot()))) +// .hasSameTextualContentAs(expectedKpiFile) +// .as("Check calculated KPI data"); + } +} From 7f8f98b75fa15a8474e19829a5b129b55105ce4a Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Thu, 25 Jan 2024 00:24:55 +0000 Subject: [PATCH 11/16] Make the refactored KPI gerenator pass the integration test --- .../kpi/matsim/run/MatsimKpiGenerator.java | 7 +- .../kpi/tablesaw/TablesawKpiCalculator.java | 73 +++++++++++++++++-- .../MatsimKpiGeneratorIntegrationTest.java | 11 +-- 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java b/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java index ad5f34a..89e4912 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java @@ -32,7 +32,7 @@ public class MatsimKpiGenerator implements Runnable { private Path matsimOutputDirectory; @Option(names = "-o", description = "Sets the output directory. Defaults to stdout", required = true) - private String outputDir; + private Path outputDir; public static void main(String[] args) { int exitCode = new CommandLine(new MatsimKpiGenerator()).execute(args); @@ -55,6 +55,7 @@ public void run() { String outputEventsFile = String.format("%s/output_events.xml.gz", matsimOutputDirectory); System.out.printf("Streaming MATSim events from %s%n", outputEventsFile); new MatsimEventsReader(eventsManager).readFile(outputEventsFile); + Map eventsSeen = matsimLinkLogHandler.getEventCounts(); Integer eventCount = eventsSeen.values() .stream() @@ -69,8 +70,6 @@ public void run() { // swallow } - // get the network link info from the matsim outputs and pass it into the calculator - - kpiCalculator.writeCongestionKpi(Path.of(format("%s/congestion-kpi.csv", outputDir))); + kpiCalculator.writeCongestionKpi(outputDir); } } diff --git a/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java index c2fb9b4..34d6242 100644 --- a/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java +++ b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java @@ -5,10 +5,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.network.Network; -import tech.tablesaw.api.DoubleColumn; -import tech.tablesaw.api.LongColumn; -import tech.tablesaw.api.StringColumn; -import tech.tablesaw.api.Table; +import tech.tablesaw.api.*; import java.nio.file.Path; import java.util.ArrayList; @@ -17,6 +14,8 @@ import java.util.Map; import java.util.stream.LongStream; +import static tech.tablesaw.aggregate.AggregateFunctions.mean; + public class TablesawKpiCalculator implements KpiCalculator { private static final Logger LOGGER = LogManager.getLogger(TablesawKpiCalculator.class); @@ -55,6 +54,7 @@ public class TablesawKpiCalculator implements KpiCalculator { public TablesawKpiCalculator(Network network) { this.network = network; + createNetworkLinkTables(network); } @Override @@ -94,8 +94,62 @@ public void recordVehicleMode(String vehicleId, String mode) { } @Override - public void writeCongestionKpi(Path directory) { - System.out.printf("Writing Congestion KPIs to %s", directory); + public void writeCongestionKpi(Path outputDirectory) { + System.out.printf("Writing Congestion KPIs to %s", outputDirectory); + System.out.println("Computing - Congestion KPI"); + Table linkLog = getLinkLog(); + + // compute travel time on links + linkLog.addColumns( + linkLog.doubleColumn("endTime") + .subtract(linkLog.doubleColumn("startTime")) + .setName("travelTime") + ); + + // compute free flow time on links (length / freespeed) + networkLinks.addColumns( + networkLinks.doubleColumn("length") + .divide(networkLinks.doubleColumn("freespeed")) + .setName("freeFlowTime") + ); + + // add freeflow time to link log + linkLog = + linkLog + .joinOn("linkID") + .inner(networkLinks.selectColumns("linkID", "freeFlowTime")); + + // compute delay ratio + linkLog.addColumns( + linkLog.doubleColumn("travelTime") + .divide(linkLog.doubleColumn("freeFlowTime")) + .setName("delayRatio") + ); + + // put in hour bins + IntColumn hour = IntColumn.create("hour"); + linkLog.doubleColumn("endTime") + .forEach(time -> hour.append( + (int) Math.floor(time / (60 * 60)) + )); + linkLog.addColumns(hour); + + // intermediate output data + Table intermediate = + linkLog + .summarize("delayRatio", mean) + .by("linkID", "mode", "hour"); + intermediate.write().csv(String.format("%s/congestion.csv", outputDirectory)); + + // kpi output + Table kpi = + linkLog + .where(linkLog.intColumn("hour").isGreaterThanOrEqualTo(7) + .and(linkLog.intColumn("hour").isLessThanOrEqualTo(9))) + .summarize("delayRatio", mean) + .by("mode") + .setName("Congestion KPI"); + kpi.write().csv(String.format("%s/kpi.csv", outputDirectory)); } private void newLinkLogEntry(String vehicleID, String linkID, String mode, double startTime) { @@ -205,4 +259,11 @@ private void createNetworkLinkTables(Network network) { StringColumn.create("mode", modesColumn) ); } + + private void writeIntermediateData(String outputDir) { + getLinkLog().write().csv(String.format("%s/linkLog.csv", outputDir)); + getVehicleOccupancy().write().csv(String.format("%s/vehicleOccupancy.csv", outputDir)); + networkLinks.write().csv(String.format("%s/networkLinks.csv", outputDir)); + networkLinkModes.write().csv(String.format("%s/networkLinkModes.csv", outputDir)); + } } diff --git a/src/test/java/com/arup/cml/abm/kpi/integration/MatsimKpiGeneratorIntegrationTest.java b/src/test/java/com/arup/cml/abm/kpi/integration/MatsimKpiGeneratorIntegrationTest.java index 6c687cb..ff6b211 100644 --- a/src/test/java/com/arup/cml/abm/kpi/integration/MatsimKpiGeneratorIntegrationTest.java +++ b/src/test/java/com/arup/cml/abm/kpi/integration/MatsimKpiGeneratorIntegrationTest.java @@ -31,12 +31,9 @@ public void testApp() throws Exception { ); assertThat(exitCode).isEqualTo(0).as("App return code should be zero"); -// String[] outputFilesList = appOutputDir.getRoot().list(); -// assertThat(outputFilesList).hasSize(6).as("Check number of output files created"); -// assertThat(outputFilesList).contains("kpi.csv").as("Check KPI CSV file exists"); -// File expectedKpiFile = new File(String.format("%s/expected-kpi.csv", testDataDirRoot)); -// assertThat(new File(String.format("%s/kpi.csv", appOutputDir.getRoot()))) -// .hasSameTextualContentAs(expectedKpiFile) -// .as("Check calculated KPI data"); + File expectedKpiFile = new File(String.format("%s/expected-kpi.csv", testDataDirRoot)); + assertThat(new File(String.format("%s/kpi.csv", appOutputDir.getRoot()))) + .hasSameTextualContentAs(expectedKpiFile) + .as("Check calculated KPI data"); } } From 84628e145200450a3ecc8c73a09fb18fd3dc90dc Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Thu, 25 Jan 2024 00:44:03 +0000 Subject: [PATCH 12/16] Tidy up the new KPI generator classes --- .../arup/cml/abm/kpi/matsim/MatsimUtils.java | 2 +- .../kpi/matsim/run/MatsimKpiGenerator.java | 22 ++++++++----------- .../kpi/tablesaw/TablesawKpiCalculator.java | 3 +-- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/MatsimUtils.java b/src/main/java/com/arup/cml/abm/kpi/matsim/MatsimUtils.java index 1514aec..9207bc7 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/MatsimUtils.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/MatsimUtils.java @@ -40,7 +40,7 @@ public MatsimUtils(Path matsimOutputDir, Path matsimConfigFile) { NetworkConfigGroup.GROUP_NAME )); - public Config getConfig(String matsimInputConfig) { + private Config getConfig(String matsimInputConfig) { Config config = ConfigUtils.createConfig(); TreeMap configuredModules = config.getModules(); for (ConfigGroup module : configuredModules.values().stream().toList()) { diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java b/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java index 89e4912..7511d3a 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java @@ -1,10 +1,7 @@ package com.arup.cml.abm.kpi.matsim.run; -import com.arup.cml.abm.kpi.KPIDomainModel; import com.arup.cml.abm.kpi.KpiCalculator; -import com.arup.cml.abm.kpi.matsim.MATSimModel; import com.arup.cml.abm.kpi.matsim.MatsimUtils; -import com.arup.cml.abm.kpi.matsim.handlers.LinkLogHandler; import com.arup.cml.abm.kpi.matsim.handlers.MatsimLinkLogHandler; import com.arup.cml.abm.kpi.tablesaw.TablesawKpiCalculator; import com.fasterxml.jackson.core.JsonProcessingException; @@ -17,12 +14,9 @@ import picocli.CommandLine.Option; import java.nio.file.Path; -import java.util.Arrays; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; -import static java.lang.String.format; - @Command(name = "MatsimKpiGenerator", version = "1.0-SNAPSHOT", mixinStandardHelpOptions = true) public class MatsimKpiGenerator implements Runnable { @Option(names = "-mc", description = "Sets the MATSim config file to use.", required = true) @@ -41,10 +35,12 @@ public static void main(String[] args) { @Override public void run() { - System.out.printf("Writing KPI metrics to %s, generated from MATSim outputs at %s, using MATSim config %s%n", + System.out.printf( + "Writing KPI metrics to %s, generated from MATSim outputs at %s, using MATSim config %s%n", outputDir, matsimOutputDirectory, - matsimConfigFile); + matsimConfigFile + ); MatsimUtils matsimUtils = new MatsimUtils(matsimOutputDirectory, matsimConfigFile); KpiCalculator kpiCalculator = new TablesawKpiCalculator(matsimUtils.getMatsimNetwork()); @@ -52,22 +48,22 @@ public void run() { EventsManager eventsManager = EventsUtils.createEventsManager(); eventsManager.addHandler(matsimLinkLogHandler); - String outputEventsFile = String.format("%s/output_events.xml.gz", matsimOutputDirectory); - System.out.printf("Streaming MATSim events from %s%n", outputEventsFile); - new MatsimEventsReader(eventsManager).readFile(outputEventsFile); + String eventsFile = String.format("%s/output_events.xml.gz", matsimOutputDirectory); + System.out.printf("Streaming MATSim events from %s%n", eventsFile); + new MatsimEventsReader(eventsManager).readFile(eventsFile); Map eventsSeen = matsimLinkLogHandler.getEventCounts(); Integer eventCount = eventsSeen.values() .stream() .mapToInt(AtomicInteger::intValue) .sum(); - System.out.printf("Recorded %,d relevant MATSim events from %s%n", eventCount, outputEventsFile); + System.out.printf("Recorded %,d relevant MATSim events from %s%n", eventCount, eventsFile); try { System.out.println(new ObjectMapper(). writerWithDefaultPrettyPrinter(). writeValueAsString(eventsSeen)); } catch (JsonProcessingException e) { - // swallow + // swallow, we're only trying to display event type counts } kpiCalculator.writeCongestionKpi(outputDir); diff --git a/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java index 34d6242..88e44d5 100644 --- a/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java +++ b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java @@ -95,8 +95,7 @@ public void recordVehicleMode(String vehicleId, String mode) { @Override public void writeCongestionKpi(Path outputDirectory) { - System.out.printf("Writing Congestion KPIs to %s", outputDirectory); - System.out.println("Computing - Congestion KPI"); + System.out.printf("Writing Congestion KPIs to %s%n", outputDirectory); Table linkLog = getLinkLog(); // compute travel time on links From 65bcc1c4c1f6d0efe08644b406608039943f0ef3 Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Thu, 25 Jan 2024 00:57:24 +0000 Subject: [PATCH 13/16] Fix PMD errors --- .../java/com/arup/cml/abm/kpi/KpiCalculator.java | 12 ++++++------ .../kpi/matsim/handlers/MatsimLinkLogHandler.java | 1 - .../cml/abm/kpi/matsim/run/MatsimKpiGenerator.java | 1 + .../cml/abm/kpi/tablesaw/TablesawKpiCalculator.java | 13 +++++-------- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/arup/cml/abm/kpi/KpiCalculator.java b/src/main/java/com/arup/cml/abm/kpi/KpiCalculator.java index 00fe36d..b5ab46b 100644 --- a/src/main/java/com/arup/cml/abm/kpi/KpiCalculator.java +++ b/src/main/java/com/arup/cml/abm/kpi/KpiCalculator.java @@ -4,10 +4,10 @@ public interface KpiCalculator { - public void linkEntered(String vehicleId, String linkId, double timestamp); - public void linkExited(String vehicleId, String linkId, double timestamp); - public void vehicleEntered(String vehicleId, String personId); - public void vehicleExited(String vehicleId, String personId); - public void recordVehicleMode(String vehicleId, String mode); - public void writeCongestionKpi(Path directory); + void linkEntered(String vehicleId, String linkId, double timestamp); + void linkExited(String vehicleId, String linkId, double timestamp); + void vehicleEntered(String vehicleId, String personId); + void vehicleExited(String vehicleId, String personId); + void recordVehicleMode(String vehicleId, String mode); + void writeCongestionKpi(Path directory); } diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/MatsimLinkLogHandler.java b/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/MatsimLinkLogHandler.java index 550ec68..c9bc8b4 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/MatsimLinkLogHandler.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/MatsimLinkLogHandler.java @@ -17,7 +17,6 @@ public class MatsimLinkLogHandler implements LinkLeaveEventHandler { private KpiCalculator kpiCalculator; - private int eventCount; private Map eventCounts = new HashMap<>(); public MatsimLinkLogHandler(KpiCalculator kpiCalculator) { diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java b/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java index 7511d3a..1b63bf3 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java @@ -64,6 +64,7 @@ public void run() { writeValueAsString(eventsSeen)); } catch (JsonProcessingException e) { // swallow, we're only trying to display event type counts + e.printStackTrace(); } kpiCalculator.writeCongestionKpi(outputDir); diff --git a/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java index 88e44d5..7863156 100644 --- a/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java +++ b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java @@ -1,7 +1,6 @@ package com.arup.cml.abm.kpi.tablesaw; import com.arup.cml.abm.kpi.KpiCalculator; -import com.arup.cml.abm.kpi.matsim.MATSimModel; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.network.Network; @@ -20,7 +19,7 @@ public class TablesawKpiCalculator implements KpiCalculator { private static final Logger LOGGER = LogManager.getLogger(TablesawKpiCalculator.class); - private Map vehicleModes = new HashMap<>(); + private final Map vehicleModes = new HashMap<>(); // arrays to collect Link Log data, each will form a column of the Link Log private final ArrayList vehicleIDColumn = new ArrayList<>(); @@ -45,15 +44,12 @@ public class TablesawKpiCalculator implements KpiCalculator { // Link Log entry index private long index = 0; - // TODO: 24/01/2024 replace this ASAP with a representation of the network - // that isn't from the MATSim API (a map, or dedicated domain object, or whatever) - private Network network; - private Table networkLinks; private Table networkLinkModes; public TablesawKpiCalculator(Network network) { - this.network = network; + // TODO: 24/01/2024 replace this ASAP with a representation of the network + // that isn't from the MATSim API (a map, or dedicated domain object, or whatever) createNetworkLinkTables(network); } @@ -149,6 +145,7 @@ public void writeCongestionKpi(Path outputDirectory) { .by("mode") .setName("Congestion KPI"); kpi.write().csv(String.format("%s/kpi.csv", outputDirectory)); + writeIntermediateData(outputDirectory); } private void newLinkLogEntry(String vehicleID, String linkID, String mode, double startTime) { @@ -259,7 +256,7 @@ private void createNetworkLinkTables(Network network) { ); } - private void writeIntermediateData(String outputDir) { + private void writeIntermediateData(Path outputDir) { getLinkLog().write().csv(String.format("%s/linkLog.csv", outputDir)); getVehicleOccupancy().write().csv(String.format("%s/vehicleOccupancy.csv", outputDir)); networkLinks.write().csv(String.format("%s/networkLinks.csv", outputDir)); From 7fec7c6addd44c079f8b903224aa354f43e46115 Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Thu, 25 Jan 2024 01:33:18 +0000 Subject: [PATCH 14/16] Add more assertions to the new integration test --- src/main/java/com/arup/cml/abm/kpi/LinkLog.java | 4 ---- .../kpi/integration/MatsimKpiGeneratorIntegrationTest.java | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 src/main/java/com/arup/cml/abm/kpi/LinkLog.java diff --git a/src/main/java/com/arup/cml/abm/kpi/LinkLog.java b/src/main/java/com/arup/cml/abm/kpi/LinkLog.java deleted file mode 100644 index c38f762..0000000 --- a/src/main/java/com/arup/cml/abm/kpi/LinkLog.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.arup.cml.abm.kpi; - -public interface LinkLog { -} diff --git a/src/test/java/com/arup/cml/abm/kpi/integration/MatsimKpiGeneratorIntegrationTest.java b/src/test/java/com/arup/cml/abm/kpi/integration/MatsimKpiGeneratorIntegrationTest.java index ff6b211..9fb3e21 100644 --- a/src/test/java/com/arup/cml/abm/kpi/integration/MatsimKpiGeneratorIntegrationTest.java +++ b/src/test/java/com/arup/cml/abm/kpi/integration/MatsimKpiGeneratorIntegrationTest.java @@ -31,6 +31,9 @@ public void testApp() throws Exception { ); assertThat(exitCode).isEqualTo(0).as("App return code should be zero"); + String[] outputFilesList = appOutputDir.getRoot().list(); + assertThat(outputFilesList).hasSize(6).as("Check number of output files created"); + assertThat(outputFilesList).contains("kpi.csv").as("Check KPI CSV file exists"); File expectedKpiFile = new File(String.format("%s/expected-kpi.csv", testDataDirRoot)); assertThat(new File(String.format("%s/kpi.csv", appOutputDir.getRoot()))) .hasSameTextualContentAs(expectedKpiFile) From 181a504b4d0cc8d7b9257270d796ea59ec86b1a0 Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Thu, 25 Jan 2024 02:11:17 +0000 Subject: [PATCH 15/16] Tidy up the new KPI generator classes --- .gitignore | 2 +- dependency-reduced-pom.xml | 2 +- pom.xml | 2 +- .../java/com/arup/cml/abm/kpi/KpiCalculator.java | 1 - .../com/arup/cml/abm/kpi/matsim/MatsimUtils.java | 16 ++++++---------- .../matsim/handlers/MatsimLinkLogHandler.java | 6 +++--- .../abm/kpi/matsim/run/MatsimKpiGenerator.java | 14 ++++++++------ .../abm/kpi/tablesaw/TablesawKpiCalculator.java | 4 +--- 8 files changed, 21 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index a3f1b32..02a647e 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,4 @@ hs_err_pid* replay_pid* target/ -gelato.iml +*.iml diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 67a044c..d5b1425 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -220,7 +220,7 @@ 17 - com.arup.cml.abm.kpi.matsim.run.KpiGenerator + com.arup.cml.abm.kpi.matsim.run.MatsimKpiGenerator 17 UTF-8 17 diff --git a/pom.xml b/pom.xml index 31eaca0..0c7f76a 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ UTF-8 UTF-8 17 - com.arup.cml.abm.kpi.matsim.run.KpiGenerator + com.arup.cml.abm.kpi.matsim.run.MatsimKpiGenerator 17 17 diff --git a/src/main/java/com/arup/cml/abm/kpi/KpiCalculator.java b/src/main/java/com/arup/cml/abm/kpi/KpiCalculator.java index b5ab46b..784fefe 100644 --- a/src/main/java/com/arup/cml/abm/kpi/KpiCalculator.java +++ b/src/main/java/com/arup/cml/abm/kpi/KpiCalculator.java @@ -3,7 +3,6 @@ import java.nio.file.Path; public interface KpiCalculator { - void linkEntered(String vehicleId, String linkId, double timestamp); void linkExited(String vehicleId, String linkId, double timestamp); void vehicleEntered(String vehicleId, String personId); diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/MatsimUtils.java b/src/main/java/com/arup/cml/abm/kpi/matsim/MatsimUtils.java index 9207bc7..f9d2807 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/MatsimUtils.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/MatsimUtils.java @@ -1,6 +1,5 @@ package com.arup.cml.abm.kpi.matsim; -import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Network; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigGroup; @@ -17,18 +16,9 @@ import java.util.TreeMap; public class MatsimUtils { - private Path matsimOutputDir; private Network matsimNetwork; private Config matsimConfig; - private Scenario matsimScenario; - - public MatsimUtils(Path matsimOutputDir, Path matsimConfigFile) { - this.matsimOutputDir = matsimOutputDir; - this.matsimConfig = getConfig(matsimConfigFile.toString()); - this.matsimScenario = ScenarioUtils.loadScenario(matsimConfig); - this.matsimNetwork = matsimScenario.getNetwork(); - } private final Set necessaryConfigGroups = new HashSet<>(Arrays.asList( GlobalConfigGroup.GROUP_NAME, @@ -40,6 +30,12 @@ public MatsimUtils(Path matsimOutputDir, Path matsimConfigFile) { NetworkConfigGroup.GROUP_NAME )); + public MatsimUtils(Path matsimOutputDir, Path matsimConfigFile) { + this.matsimOutputDir = matsimOutputDir; + this.matsimConfig = getConfig(matsimConfigFile.toString()); + this.matsimNetwork = ScenarioUtils.loadScenario(matsimConfig).getNetwork(); + } + private Config getConfig(String matsimInputConfig) { Config config = ConfigUtils.createConfig(); TreeMap configuredModules = config.getModules(); diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/MatsimLinkLogHandler.java b/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/MatsimLinkLogHandler.java index c9bc8b4..248838b 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/MatsimLinkLogHandler.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/handlers/MatsimLinkLogHandler.java @@ -17,7 +17,7 @@ public class MatsimLinkLogHandler implements LinkLeaveEventHandler { private KpiCalculator kpiCalculator; - private Map eventCounts = new HashMap<>(); + private final Map eventCounts = new HashMap<>(); public MatsimLinkLogHandler(KpiCalculator kpiCalculator) { this.kpiCalculator = kpiCalculator; @@ -89,7 +89,7 @@ public Map getEventCounts() { } private void incrementEventCount(Event e) { - this.eventCounts.putIfAbsent(e.getEventType(), new AtomicInteger(0)); - this.eventCounts.get(e.getEventType()).incrementAndGet(); + eventCounts.putIfAbsent(e.getEventType(), new AtomicInteger(0)); + eventCounts.get(e.getEventType()).incrementAndGet(); } } diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java b/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java index 1b63bf3..9643dae 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java @@ -51,22 +51,24 @@ public void run() { String eventsFile = String.format("%s/output_events.xml.gz", matsimOutputDirectory); System.out.printf("Streaming MATSim events from %s%n", eventsFile); new MatsimEventsReader(eventsManager).readFile(eventsFile); + summariseEventsHandled(eventsFile, matsimLinkLogHandler.getEventCounts()); - Map eventsSeen = matsimLinkLogHandler.getEventCounts(); - Integer eventCount = eventsSeen.values() + kpiCalculator.writeCongestionKpi(outputDir); + } + + private static void summariseEventsHandled(String eventsFilePath, Map eventCounts) { + Integer eventCount = eventCounts.values() .stream() .mapToInt(AtomicInteger::intValue) .sum(); - System.out.printf("Recorded %,d relevant MATSim events from %s%n", eventCount, eventsFile); + System.out.printf("Recorded %,d relevant MATSim events from %s%n", eventCount, eventsFilePath); try { System.out.println(new ObjectMapper(). writerWithDefaultPrettyPrinter(). - writeValueAsString(eventsSeen)); + writeValueAsString(eventCounts)); } catch (JsonProcessingException e) { // swallow, we're only trying to display event type counts e.printStackTrace(); } - - kpiCalculator.writeCongestionKpi(outputDir); } } diff --git a/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java index 7863156..d508cef 100644 --- a/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java +++ b/src/main/java/com/arup/cml/abm/kpi/tablesaw/TablesawKpiCalculator.java @@ -16,7 +16,6 @@ import static tech.tablesaw.aggregate.AggregateFunctions.mean; public class TablesawKpiCalculator implements KpiCalculator { - private static final Logger LOGGER = LogManager.getLogger(TablesawKpiCalculator.class); private final Map vehicleModes = new HashMap<>(); @@ -38,7 +37,6 @@ public class TablesawKpiCalculator implements KpiCalculator { private final ArrayList agentIDColumn = new ArrayList<>(); // tracks the most recent occupants of a vehicle - // TODO: 24/01/2024 should this be a set? private final Map> vehicleLatestOccupants = new HashMap<>(); // Link Log entry index @@ -86,7 +84,7 @@ public void vehicleExited(String vehicleId, String personId) { @Override public void recordVehicleMode(String vehicleId, String mode) { - this.vehicleModes.put(vehicleId, mode); + vehicleModes.put(vehicleId, mode); } @Override From 45eb4a8181f568202b9d60783af1186975ac1646 Mon Sep 17 00:00:00 2001 From: Michael Fitzmaurice Date: Thu, 25 Jan 2024 03:58:14 +0000 Subject: [PATCH 16/16] Add comments about dependency injection --- .../com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java b/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java index 9643dae..704fde9 100644 --- a/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java +++ b/src/main/java/com/arup/cml/abm/kpi/matsim/run/MatsimKpiGenerator.java @@ -42,6 +42,11 @@ public void run() { matsimConfigFile ); + // We're not using a dependency injection framework, but we *are* programming + // in a dependency injection style (explicit dependencies passed into + // constructors) and then creating and wiring together the objects in the + // object graph "manually" here. Switching to a DI framework in future should + // be pretty straightforward if we need to. MatsimUtils matsimUtils = new MatsimUtils(matsimOutputDirectory, matsimConfigFile); KpiCalculator kpiCalculator = new TablesawKpiCalculator(matsimUtils.getMatsimNetwork()); MatsimLinkLogHandler matsimLinkLogHandler = new MatsimLinkLogHandler(kpiCalculator);