diff --git a/pom.xml b/pom.xml
index f8be78d..e6f09d2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@
- 2025.0-PR3429
+ 2025.0-PR3486
diff --git a/src/main/R/commuter-analysis.R b/src/main/R/commuter-analysis.R
new file mode 100644
index 0000000..08405ff
--- /dev/null
+++ b/src/main/R/commuter-analysis.R
@@ -0,0 +1,52 @@
+library(matsim)
+library(tidyverse)
+library(readr)
+library(sf)
+
+#FILES
+FILE_DIR = "../../shared-svn/projects/DiTriMo/data/commuters-by-town"
+SIM <- paste0(FILE_DIR, "lausitz-v1.0-commuter.csv")
+GEMEINDE <- paste0(FILE_DIR, "pgemeinden.csv")
+COMMUTER <- paste0(FILE_DIR, "commuter.csv")
+SHP <- paste0(FILE_DIR, "VG5000_GEM/VG5000_GEM.shp")
+LAUSITZ.SHP <- paste0(FILE_DIR, "network-area/network-area.shp")
+
+shp <- st_read(SHP)
+lausitz.shp <- st_read(LAUSITZ.SHP)
+
+sim <- read_csv(file = SIM)
+gemeinden <- read_csv( file = GEMEINDE) %>%
+ mutate(code = str_remove(string = code, pattern = "P"))
+
+commuter <- read_csv(file = COMMUTER) %>%
+ mutate(key = paste0(from, "-", to))
+
+sim.1 <- sim %>%
+ filter(!is.na(from) & !is.na(to)) %>%
+ left_join(gemeinden, by = c("from" = "code")) %>%
+ left_join(gemeinden, by = c("from" = "code"), suffix = c("_from", "_to")) %>%
+ mutate(key = paste0(from, "-", to)) %>%
+ select(-c(from, to)) %>%
+ left_join(commuter, by = "key", suffix = c("_sim", "_real")) %>%
+ filter(!is.na(from)) %>%
+# pivot_longer(cols = starts_with("n_"), names_to = "src", values_to = "n", names_prefix = "n_") %>%
+ arrange(desc(n_real))
+
+breaks <- c(-Inf, 0.8, 1.2, Inf)
+labels <- c("less", "exakt", "more")
+
+sim.2 <- sim.1 %>%
+ filter(n_sim > 10) %>%
+ select(from, to, starts_with("n_"), starts_with("name_")) %>%
+ mutate(n_rel = n_sim / n_real,
+ quality = cut(n_rel, breaks = breaks, labels = labels))
+
+ggplot(sim.2, aes(x = n_real, y = n_sim, col = quality)) +
+
+ geom_point() +
+
+ scale_x_log10() +
+
+ scale_y_log10() +
+
+ theme_bw()
diff --git a/src/main/R/counts.R b/src/main/R/counts.R
index 46adb56..82a1354 100644
--- a/src/main/R/counts.R
+++ b/src/main/R/counts.R
@@ -4,10 +4,10 @@ devtools::install_github("matsim-vsp/matsim-r",ref="counts")
library(matsim)
library(tidyverse)
-COUNTS <- "Y:/matsim-lausitz/input/v1.0/lausitz-v1.0-counts-car-bast.xml.gz"
-NETWORK <- "Y:/matsim-lausitz/input/v1.0/lausitz-v1.0-network-with-pt.xml.gz"
+COUNTS <- "../../public-svn/matsim/scenarios/countries/de/lausitz/input/v1.0/lausitz-v1.0-counts-car-bast.xml.gz"
+NETWORK <- "../../public-svn/matsim/scenarios/countries/de/lausitz/input/v1.0/lausitz-v1.0-network-with-pt.xml.gz"
-linkstats <- readLinkStats(runId = "v1.0-uncalibrated", file = "Y:/matsim-lausitz/qa/output/lausitz-25pct.output_linkstats.csv.gz")
+linkstats <- readLinkStats(runId = "v1.0-uncalibrated", file = "Y:/matsim-lausitz/qa/output/lausitz-25pct.output_linkstats.csv.gz", sampleSize = 1)
counts <- readCounts(COUNTS)
network <- loadNetwork(NETWORK)
@@ -17,7 +17,7 @@ join <- mergeCountsAndLinks(counts = counts, linkStats = list(linkstats), netwo
#### VIA-styled scatterplot ####
-FILE_DIR = "C:/Users/ACER/Desktop/Uni/VSP/Lausitz-Plots/"
+FILE_DIR = "../../shared-svn/projects/DiTriMo/data/commuters-by-town"
createCountScatterPlot(joinedFrame = join)
ggsave(filename = paste0(FILE_DIR, "Traffic_Count_Scatterplot_with_freight.jpg"))
@@ -43,7 +43,7 @@ rm(join.dtv.distribution)
#### Analysis of Estimation Quality ####
-join.est.quality <- processDtvEstimationQuality(joinedFrame = join, aggr = T) %>%
+join.est.quality <- processDtvEstimationQuality(joinedFrame = join, aggr = F) %>%
filter(!type %in% c("residential", "unclassified", NA))
ggplot(join.est.quality, aes(estimation, share, fill = type)) +
@@ -59,4 +59,26 @@ ggplot(join.est.quality, aes(estimation, share, fill = type)) +
theme(legend.position = "none", axis.text.x = element_text(angle = 90))
rm(join.est.quality)
-ggsave(filename = paste0(FILE_DIR, "Estimation_quality_by_road_type_with_freight.jpg"))
\ No newline at end of file
+ggsave(filename = paste0(FILE_DIR, "Estimation_quality_by_road_type_with_freight.jpg"))
+
+
+#### network plot ####
+
+library(tmap)
+library(tmaptools)
+library(OpenStreetMap)
+library(sf)
+
+link.geom <- join %>%
+ left_join(network$links, by = c("loc_id" = "id")) %>%
+ mutate(geom = sprintf("LINESTRING(%s %s, %s %s)", x.from, y.from, x.to, y.to)) %>%
+ st_as_sf(crs = 25832, wkt = "geom") %>%
+ transmute(loc_id, type.x, rel_vol = volume / count, geom)
+
+tmap_mode("view")
+
+tm_shape(shp = link.geom) +
+ tm_lines(col = "estimation", style = "cont", lwd = 3.5, palette = c("red", "green", "blue"))
+
+tm_shape(shp = link.geom) +
+ tm_lines(col = "rel_vol", style = "cont", lwd = 5, palette = c("red", "yellow", "green"), breaks = c(0, 0.05, 0.8, 2))
diff --git a/src/main/java/org/matsim/dashboards/LausitzDashboardProvider.java b/src/main/java/org/matsim/dashboards/LausitzDashboardProvider.java
index 7c2589c..0092383 100644
--- a/src/main/java/org/matsim/dashboards/LausitzDashboardProvider.java
+++ b/src/main/java/org/matsim/dashboards/LausitzDashboardProvider.java
@@ -1,6 +1,7 @@
package org.matsim.dashboards;
import org.matsim.core.config.Config;
+import org.matsim.core.population.PersonUtils;
import org.matsim.simwrapper.Dashboard;
import org.matsim.simwrapper.DashboardProvider;
import org.matsim.simwrapper.SimWrapper;
@@ -20,8 +21,9 @@ public List getDashboards(Config config, SimWrapper simWrapper) {
"lausitz_mode_share.csv",
"lausitz_mode_share_per_dist.csv",
"lausitz_mode_users.csv")
- .withGroupedRefData("lausitz_mode_share_per_group_dist_ref.csv", "age", "economic_status")
- .withDistanceDistribution("lausitz_mode_share_distance_distribution.csv");
+ .withGroupedRefData("lausitz_mode_share_per_group_dist_ref.csv", "age", "economic_status", "income")
+ .withDistanceDistribution("lausitz_mode_share_distance_distribution.csv")
+ .setAnalysisArgs("--person-filter", "subpopulation=person");
return List.of(trips,
new EmissionsDashboard()
diff --git a/src/main/java/org/matsim/dashboards/LausitzSimWrapperRunner.java b/src/main/java/org/matsim/dashboards/LausitzSimWrapperRunner.java
index bb61bda..29e09b6 100644
--- a/src/main/java/org/matsim/dashboards/LausitzSimWrapperRunner.java
+++ b/src/main/java/org/matsim/dashboards/LausitzSimWrapperRunner.java
@@ -42,7 +42,7 @@
name = "simwrapper",
description = "Run additional analysis and create SimWrapper dashboard for existing run output."
)
-final class LausitzSimWrapperRunner implements MATSimAppCommand {
+public final class LausitzSimWrapperRunner implements MATSimAppCommand {
private static final Logger log = LogManager.getLogger(LausitzSimWrapperRunner.class);
@@ -56,7 +56,8 @@ final class LausitzSimWrapperRunner implements MATSimAppCommand {
private boolean noise;
- private LausitzSimWrapperRunner(){
+ public LausitzSimWrapperRunner(){
+// public constructor needed for testing purposes.
}
@Override
@@ -81,7 +82,7 @@ public Integer call() throws Exception {
simwrapperCfg.defaultDashboards = SimWrapperConfigGroup.Mode.disabled;
//add dashboards according to command line parameters
-// TODO: if more dashboards are to be added here, we need to check if noise==true before adding noise dashboard here
+// if more dashboards are to be added here, we need to check if noise==true before adding noise dashboard here
sw.addDashboard(Dashboard.customize(new NoiseDashboard()).context("noise"));
diff --git a/src/main/java/org/matsim/run/LausitzScenario.java b/src/main/java/org/matsim/run/LausitzScenario.java
index f7fa06b..4ecfbf7 100644
--- a/src/main/java/org/matsim/run/LausitzScenario.java
+++ b/src/main/java/org/matsim/run/LausitzScenario.java
@@ -2,10 +2,8 @@
import com.google.common.collect.Sets;
import org.matsim.analysis.personMoney.PersonMoneyEventsAnalysisModule;
-import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.TransportMode;
-import org.matsim.api.core.v01.population.Person;
import org.matsim.application.MATSimApplication;
import org.matsim.application.analysis.CheckPopulation;
import org.matsim.application.analysis.traffic.LinkStats;
@@ -31,10 +29,11 @@
import org.matsim.core.config.groups.ScoringConfigGroup;
import org.matsim.core.controler.AbstractModule;
import org.matsim.core.controler.Controler;
-import org.matsim.core.population.PopulationUtils;
import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule;
import org.matsim.core.scoring.functions.ScoringParametersForPerson;
+import org.matsim.run.analysis.CommunityFilter;
import org.matsim.run.analysis.CommuterAnalysis;
+import org.matsim.run.analysis.DistanceMatrix;
import org.matsim.run.prepare.PrepareNetwork;
import org.matsim.run.prepare.PreparePopulation;
import org.matsim.simwrapper.SimWrapperConfigGroup;
@@ -48,9 +47,6 @@
import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.List;
-import java.net.URISyntaxException;
-import java.nio.file.Paths;
-import java.util.Map;
import java.util.Set;
@CommandLine.Command(header = ":: Open Lausitz Scenario ::", version = LausitzScenario.VERSION, mixinStandardHelpOptions = true)
@@ -61,7 +57,7 @@
SplitActivityTypesDuration.class, CreateCountsFromBAStData.class, PreparePopulation.class, CleanPopulation.class, PrepareNetwork.class
})
@MATSimApplication.Analysis({
- LinkStats.class, CheckPopulation.class, CommuterAnalysis.class,
+ LinkStats.class, CheckPopulation.class, CommuterAnalysis.class, CommunityFilter.class, DistanceMatrix.class
})
public class LausitzScenario extends MATSimApplication {
@@ -79,6 +75,9 @@ public class LausitzScenario extends MATSimApplication {
private static final String HBEFA_FILE_COLD_AVERAGE = HBEFA_2020_PATH + "r9230ru2n209r30u2fn0c9rn20n2rujkhkjhoewt84202.enc" ;
private static final String HBEFA_FILE_WARM_AVERAGE = HBEFA_2020_PATH + "7eff8f308633df1b8ac4d06d05180dd0c5fdf577.enc";
+ @CommandLine.Option(names = "--alpha", description = "alpha for ride, this is just to get a feeling for the parameters dimension, should never be configurable in release.", defaultValue = "2.")
+ private double alpha;
+
@CommandLine.Mixin
private final SampleOptions sample = new SampleOptions( 100, 25, 10, 1);
@@ -135,7 +134,7 @@ protected Config prepareConfig(Config config) {
// 2.0 + 1.0 = alpha + 1
// ride cost = alpha * car cost
// ride marg utility of traveling = (alpha + 1) * marg utility travelling car + alpha * beta perf
- double alpha = 2;
+// double alpha = 2;
rideParams.setMarginalUtilityOfTraveling((alpha + 1) * carParams.getMarginalUtilityOfTraveling() - alpha * config.scoring().getPerforming_utils_hr());
rideParams.setDailyMonetaryConstant(0.);
rideParams.setMonetaryDistanceRate(carParams.getMonetaryDistanceRate() * 2);
@@ -155,13 +154,9 @@ protected Config prepareConfig(Config config) {
vvo20.setTransactionPartner("VVO Tarifzone 20");
vvo20.setDescription("VVO Tarifzone 20");
vvo20.setOrder(1);
- try {
- vvo20.setFareZoneShp(Paths.get(config.getContext().toURI()).getParent().toString() + "/vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.shp");
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
+ vvo20.setFareZoneShp("./vvo_tarifzone20/vvo_tarifzone20_hoyerswerda_utm32n.shp");
- DistanceBasedPtFareParams germany = DistanceBasedPtFareParams.GERMAN_WIDE_FARE;
+ DistanceBasedPtFareParams germany = DistanceBasedPtFareParams.GERMAN_WIDE_FARE_2024;
germany.setTransactionPartner("Deutschlandtarif");
germany.setDescription("Deutschlandtarif");
germany.setOrder(2);
@@ -184,26 +179,6 @@ protected Config prepareConfig(Config config) {
@Override
protected void prepareScenario(Scenario scenario) {
-
-
- for (Person person : scenario.getPopulation().getPersons().values()) {
-
- if (PopulationUtils.getSubpopulation(person).contains("commercialPersonTraffic") ||
- PopulationUtils.getSubpopulation(person).contains("goodsTraffic")) {
-
- Map> types = VehicleUtils.getVehicleTypes(person);
-
- for (Map.Entry> entry : types.entrySet()) {
- if (Set.of(HEAVY_MODE, MEDIUM_MODE, LIGHT_MODE).contains(entry.getKey())) {
- types.put(entry.getKey(), Id.create(entry.getKey(), VehicleType.class));
- }
- }
- }
-
- }
-
-
-
// add freight and truck as allowed modes together with car
PrepareNetwork.prepareFreightNetwork(scenario.getNetwork());
diff --git a/src/main/java/org/matsim/run/RunLausitzPtScenario.java b/src/main/java/org/matsim/run/RunLausitzPtScenario.java
index 7dfac1e..f38b3cf 100644
--- a/src/main/java/org/matsim/run/RunLausitzPtScenario.java
+++ b/src/main/java/org/matsim/run/RunLausitzPtScenario.java
@@ -28,6 +28,10 @@ public class RunLausitzPtScenario extends MATSimApplication {
private final LausitzScenario baseScenario = new LausitzScenario();
+ public RunLausitzPtScenario(@Nullable Config config) {
+ super(config);
+ }
+
public RunLausitzPtScenario() {
super(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION));
}
diff --git a/src/main/java/org/matsim/run/analysis/CommunityFilter.java b/src/main/java/org/matsim/run/analysis/CommunityFilter.java
new file mode 100644
index 0000000..1bd1b90
--- /dev/null
+++ b/src/main/java/org/matsim/run/analysis/CommunityFilter.java
@@ -0,0 +1,80 @@
+package org.matsim.run.analysis;
+
+import org.apache.commons.csv.CSVPrinter;
+import org.geotools.api.feature.simple.SimpleFeature;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.Point;
+import org.matsim.application.MATSimAppCommand;
+import org.matsim.application.options.CsvOptions;
+import org.matsim.core.utils.collections.Tuple;
+import org.matsim.core.utils.gis.GeoFileReader;
+import picocli.CommandLine;
+
+import java.nio.file.Path;
+import java.util.*;
+
+@CommandLine.Command(name = "community-filter", description = "creates a csv with commuity keys within shape")
+public class CommunityFilter implements MATSimAppCommand {
+
+ @CommandLine.Option(names = "--community-shp", description = "path to VG5000_GEM.shp", required = true)
+ private static Path communityShapePath;
+
+ @CommandLine.Option(names = "--dilution-area", description = "path to area-of-interest-shape file", required = true)
+ private static Path dilutionAreaShapePath;
+
+ @CommandLine.Option(names = "--output", description = "output csv filepath", required = true)
+ private static Path output;
+
+ @CommandLine.Mixin
+ CsvOptions csvOptions = new CsvOptions();
+ private final Map> filtered = new HashMap<>();
+
+ public static void main(String[] args) {
+ new CommunityFilter().execute(args);
+ }
+
+ @Override
+ public Integer call() throws Exception {
+
+ Collection communities = readShapeFile(communityShapePath);
+ Collection dilutionArea = readShapeFile(dilutionAreaShapePath);
+
+ List geometries = dilutionArea.stream().map(feature -> (Geometry) feature.getDefaultGeometry()).toList();
+
+ for(var community: communities){
+
+ String attribute = (String) community.getAttribute("ARS");
+
+ if(geometries.stream()
+ .anyMatch(geometry -> geometry.covers((Geometry) community.getDefaultGeometry()))){
+
+ Point centroid = ((Geometry) community.getDefaultGeometry()).getCentroid();
+ Tuple coordinates = Tuple.of(centroid.getX(), centroid.getY());
+
+ filtered.put(attribute, coordinates);
+ }
+
+ }
+
+ try (CSVPrinter printer = csvOptions.createPrinter(output)) {
+ printer.print("ars");
+ printer.print("x");
+ printer.print("y");
+ printer.println();
+
+ for (Map.Entry> entry : filtered.entrySet()) {
+ printer.print(entry.getKey());
+ printer.print(entry.getValue().getFirst());
+ printer.print(entry.getValue().getSecond());
+ printer.println();
+ }
+ }
+
+ return 0;
+ }
+
+ private static Collection readShapeFile(Path filepath){
+
+ return GeoFileReader.getAllFeatures(filepath.toString());
+ }
+}
diff --git a/src/main/java/org/matsim/run/analysis/DistanceMatrix.java b/src/main/java/org/matsim/run/analysis/DistanceMatrix.java
new file mode 100644
index 0000000..3be4a0d
--- /dev/null
+++ b/src/main/java/org/matsim/run/analysis/DistanceMatrix.java
@@ -0,0 +1,108 @@
+package org.matsim.run.analysis;
+
+import org.apache.commons.csv.CSVPrinter;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.geotools.api.feature.simple.SimpleFeature;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.Point;
+import org.matsim.api.core.v01.Coord;
+import org.matsim.application.MATSimAppCommand;
+import org.matsim.application.options.CsvOptions;
+import org.matsim.application.options.ShpOptions;
+import org.matsim.core.utils.geometry.CoordUtils;
+import org.matsim.core.utils.geometry.geotools.MGC;
+import org.matsim.core.utils.gis.GeoFileReader;
+import picocli.CommandLine;
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Predicate;
+
+@CommandLine.Command(name = "distance-matrix", description = "creates a csv with commuity keys within shape")
+public class DistanceMatrix implements MATSimAppCommand{
+
+ @CommandLine.Option(names = "--output", description = "output csv filepath", required = true)
+ private static Path output;
+
+ @CommandLine.Option(names = "--dilution-area", description = "shape to filter zones", required = false)
+ private static Path dilutionArea;
+
+ @CommandLine.Mixin
+ CsvOptions csvOptions = new CsvOptions();
+
+ @CommandLine.Mixin
+ ShpOptions shp = new ShpOptions();
+
+ private final List distances = new ArrayList<>();
+ private static final Logger logger = LogManager.getLogger(DistanceMatrix.class);
+
+ public static void main(String[] args) {
+ new DistanceMatrix().execute(args);
+ }
+
+ @Override
+ public Integer call() throws Exception {
+
+ logger.info("Read features.");
+ List communities = shp.readFeatures();
+
+ //to prevent RuntimeExceptions
+ ArrayList copy = new ArrayList<>(communities);
+
+ Predicate filter = getFilter(dilutionArea);
+
+ logger.info("Calculate distance matrix.");
+ String delimiter = csvOptions.getFormat().getDelimiterString();
+ for(var community: communities){
+
+ if(!filter.test((Geometry) community.getDefaultGeometry()))
+ continue;
+ String nameFrom = (String) community.getAttribute("ARS");
+ Point centroid = ((Geometry) community.getDefaultGeometry()).getCentroid();
+ Coord from = MGC.point2Coord(centroid);
+ for(var target: copy){
+
+ String nameTo = (String) target.getAttribute("ARS");
+
+ Point centroid2 = ((Geometry) target.getDefaultGeometry()).getCentroid();
+ Coord to = MGC.point2Coord(centroid2);
+ double distance = CoordUtils.calcEuclideanDistance(from, to);
+
+ String distanceString = String.valueOf(distance).replace('.', ',');
+
+ distances.add(nameFrom + delimiter + nameTo + delimiter + distanceString);
+ }
+ }
+
+ logger.info("Print results to {}", output);
+ try (CSVPrinter printer = csvOptions.createPrinter(output)) {
+ printer.print("from");
+ printer.print("to");
+ printer.print("distance");
+ printer.println();
+
+ for (String entry : distances) {
+ for (String col : entry.split(csvOptions.getFormat().getDelimiterString()))
+ printer.print(col);
+ printer.println();
+ }
+ }
+
+ logger.info("Done!");
+ return 0;
+ }
+
+ private Predicate getFilter(Path path){
+
+ if(path == null)
+ return community -> true;
+
+ List geometries = GeoFileReader.getAllFeatures(path.toString()).stream()
+ .map(feature -> (Geometry) feature.getDefaultGeometry())
+ .toList();
+
+ return community -> geometries.stream().anyMatch(geometry -> geometry.covers(community));
+ }
+}
diff --git a/src/main/java/org/matsim/run/prepare/PrepareNetwork.java b/src/main/java/org/matsim/run/prepare/PrepareNetwork.java
index ade17b5..5ad8bfa 100644
--- a/src/main/java/org/matsim/run/prepare/PrepareNetwork.java
+++ b/src/main/java/org/matsim/run/prepare/PrepareNetwork.java
@@ -91,14 +91,6 @@ public static void prepareFreightNetwork(Network network) {
public static void prepareEmissionsAttributes(Network network) {
// do not use VspHbefaRoadTypeMapping() as it results in almost every road to mapped to "highway"!
HbefaRoadTypeMapping roadTypeMapping = OsmHbefaMapping.build();
-// the type attribute in our network has the prefix "highway" for all links but pt links.
-// we need to delete that because OsmHbefaMapping does not handle that.
- for (Link link : network.getLinks().values()) {
- //pt links can be disregarded
- if (!link.getAllowedModes().contains("pt")) {
- NetworkUtils.setType(link, NetworkUtils.getType(link).replaceFirst("highway.", ""));
- }
- }
roadTypeMapping.addHbefaMappings(network);
}
diff --git a/src/test/java/org/matsim/run/EmissionAnalysisOutputTest.java b/src/test/java/org/matsim/run/EmissionAnalysisOutputTest.java
deleted file mode 100644
index cfeeab0..0000000
--- a/src/test/java/org/matsim/run/EmissionAnalysisOutputTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package org.matsim.run;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
-import org.junit.jupiter.api.io.TempDir;
-import org.matsim.api.core.v01.Coord;
-import org.matsim.api.core.v01.Id;
-import org.matsim.api.core.v01.TransportMode;
-import org.matsim.api.core.v01.population.*;
-import org.matsim.application.MATSimApplication;
-import org.matsim.core.config.Config;
-import org.matsim.core.config.ConfigUtils;
-import org.matsim.core.population.PersonUtils;
-import org.matsim.core.population.PopulationUtils;
-import org.matsim.core.utils.io.IOUtils;
-import org.matsim.testcases.MatsimTestUtils;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.matsim.application.ApplicationUtils.globFile;
-
-class EmissionAnalysisOutputTest {
-
- @RegisterExtension
- public MatsimTestUtils utils = new MatsimTestUtils();
-
- @TempDir
- public Path p;
-
- private final static Id ptPersonId = Id.createPersonId("Hoyerswerda-Cottbus_CAR");
-
- @Test
- void runEmissionAnalysisOutputTest() throws IOException {
- Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION));
-
- Path inputPath = p.resolve("emissions-test-population.xml.gz");
-
- Population population = PopulationUtils.createPopulation(config);
- PopulationFactory fac = population.getFactory();
- Person person = fac.createPerson(ptPersonId);
- Plan plan = PopulationUtils.createPlan(person);
-
-// home in hoyerswerda, nearest link 28922425#0
- Activity home = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24));
- home.setEndTime(8 * 3600);
- Activity home2 = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24));
- home2.setEndTime(19 * 3600);
-// work in hoyerswerda, nearest link(s): 686055693#1, -686055693#1
- Activity work = fac.createActivityFromCoord("work_2400", new Coord(863866.47,5710961.86));
- work.setEndTime(17 * 3600 + 25 * 60);
-
- Leg leg = fac.createLeg(TransportMode.car);
-
- plan.addActivity(home);
- plan.addLeg(leg);
- plan.addActivity(work);
- plan.addLeg(leg);
- plan.addActivity(home2);
-
- person.addPlan(plan);
- PersonUtils.setIncome(person, 1000.);
- person.getAttributes().putAttribute("subpopulation", "person");
- population.addPerson(person);
-
- new PopulationWriter(population).write(inputPath.toString());
-
- assert MATSimApplication.execute(LausitzScenario.class, config,
- "--1pct",
- "--iterations", "0",
- "--output", utils.getOutputDirectory(),
- "--config:plans.inputPlansFile", inputPath.toString(),
- "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code";
-
-
- Path csvPath = globFile(Path.of(utils.getOutputDirectory() + "/analysis/emissions"), "*emissions_per_link.csv*");
-
- Map nonZeroLinks = new HashMap<>();
-
- try {
- BufferedReader reader = IOUtils.getBufferedReader(csvPath.toUri().toURL());
- String line;
-
-// skip header
- reader.readLine();
-
- while ((line = reader.readLine()) != null) {
- String[] parts = line.split(",");
-
-// if first value (CO) is zero, all others are too
- if (Double.parseDouble(parts[1]) == 0.) {
- continue;
- }
-
- Double[] values = new Double[23];
-
- for (int i = 1; i < parts.length; i++) {
- values[i - 1] = Double.parseDouble(parts[i]);
- }
-
- nonZeroLinks.put(parts[0], values);
- }
- } finally {
-
- }
-
- Assertions.assertFalse(nonZeroLinks.isEmpty());
- Assertions.assertTrue(nonZeroLinks.containsKey("28922425#0"));
- Assertions.assertTrue(nonZeroLinks.containsKey("-686055693#1"));
- }
-}
diff --git a/src/test/java/org/matsim/run/EmissionAndNoiseAnalysisOutputTest.java b/src/test/java/org/matsim/run/EmissionAndNoiseAnalysisOutputTest.java
new file mode 100644
index 0000000..f4cd898
--- /dev/null
+++ b/src/test/java/org/matsim/run/EmissionAndNoiseAnalysisOutputTest.java
@@ -0,0 +1,186 @@
+package org.matsim.run;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.io.TempDir;
+import org.matsim.api.core.v01.Coord;
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.TransportMode;
+import org.matsim.api.core.v01.population.*;
+import org.matsim.application.MATSimApplication;
+import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigUtils;
+import org.matsim.core.population.PersonUtils;
+import org.matsim.core.population.PopulationUtils;
+import org.matsim.core.utils.io.IOUtils;
+import org.matsim.dashboards.LausitzSimWrapperRunner;
+import org.matsim.simwrapper.SimWrapperConfigGroup;
+import org.matsim.testcases.MatsimTestUtils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static org.matsim.application.ApplicationUtils.globFile;
+
+class EmissionAndNoiseAnalysisOutputTest {
+
+ @RegisterExtension
+ public MatsimTestUtils utils = new MatsimTestUtils();
+
+ @TempDir
+ public Path p;
+
+ private final static Id carPersonId = Id.createPersonId("Hoyerswerda-Cottbus_CAR");
+
+ private static Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION));
+
+ @Disabled("Test is used to secure functionality of emission analysis. As the analysis needs" +
+ "a lot of RAM, it is disabled and only run manually. -sme0924")
+ @Test
+ void runEmissionAnalysisOutputTest() throws IOException {
+// Here, we do want dashboards in general (emission dashboard), but do not want to waste computation time on the standard dashboards
+ ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class).exclude = Set.of("TripDashboard", "OverviewDashboard", "StuckAgentDashboard",
+ "TrafficCountsDashboard", "TrafficDashboard", "PublicTransitDashboard");
+
+ Path inputPath = p.resolve("test-population.xml.gz");
+ createTestPopulation(inputPath);
+
+ assert MATSimApplication.execute(LausitzScenario.class, config,
+ "--1pct",
+ "--iterations", "0",
+ "--output", utils.getOutputDirectory(),
+ "--config:plans.inputPlansFile", inputPath.toString(),
+ "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code";
+
+
+ Path csvPath = globFile(Path.of(utils.getOutputDirectory() + "/analysis/emissions"), "*emissions_per_link.csv*");
+
+ Map nonZeroLinks = new HashMap<>();
+
+ try {
+ BufferedReader reader = IOUtils.getBufferedReader(csvPath.toUri().toURL());
+ String line;
+
+// skip header
+ reader.readLine();
+
+ while ((line = reader.readLine()) != null) {
+ String[] parts = line.split(",");
+
+// if first value (CO) is zero, all others are too
+ if (Double.parseDouble(parts[1]) == 0.) {
+ continue;
+ }
+
+ Double[] values = new Double[23];
+
+ for (int i = 1; i < parts.length; i++) {
+ values[i - 1] = Double.parseDouble(parts[i]);
+ }
+
+ nonZeroLinks.put(parts[0], values);
+ }
+ } finally {
+
+ }
+
+ Assertions.assertFalse(nonZeroLinks.isEmpty());
+ Assertions.assertTrue(nonZeroLinks.containsKey("28922425#0"));
+ Assertions.assertTrue(nonZeroLinks.containsKey("-686055693#1"));
+// CO
+ Assertions.assertEquals(830.9171, nonZeroLinks.get("28922425#0")[0], 0.0001);
+ Assertions.assertEquals(700.632, nonZeroLinks.get("-686055693#1")[0], 0.001);
+// CO2_TOTAL
+ Assertions.assertEquals(8029.8788, nonZeroLinks.get("28922425#0")[1], 0.0001);
+ Assertions.assertEquals(6114.849, nonZeroLinks.get("-686055693#1")[1], 0.001);
+ }
+
+ @Disabled("Test is used to secure functionality of noise analysis. As the analysis needs" +
+ "a lot of RAM, it is disabled and only run manually. -sme0924")
+ @Test
+ void runNoiseAnalysisOutputTest() throws IOException {
+// Here, we do want dashboards in general (emission dashboard), but do not want to waste computation time on the standard dashboards
+ ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class).defaultDashboards = SimWrapperConfigGroup.Mode.disabled;
+
+ Path inputPath = p.resolve("test-population.xml.gz");
+ createTestPopulation(inputPath);
+
+ assert MATSimApplication.execute(LausitzScenario.class, config,
+ "--1pct",
+ "--iterations", "0",
+ "--output", utils.getOutputDirectory(),
+ "--config:plans.inputPlansFile", inputPath.toString(),
+ "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code";
+
+ new LausitzSimWrapperRunner().execute(utils.getOutputDirectory(), "--noise", "--shp", "../../../../../../../input/shp/lausitz.shp");
+
+ Path csvPath = globFile(Path.of(utils.getOutputDirectory() + "/analysis/noise-noise"), "*emission_per_day.csv*");
+
+ Map nonZeroLinks = new HashMap<>();
+
+ try {
+ BufferedReader reader = IOUtils.getBufferedReader(csvPath.toUri().toURL());
+ String line;
+
+// skip header
+ reader.readLine();
+
+ while ((line = reader.readLine()) != null) {
+ String[] parts = line.split(",");
+
+ if (Double.parseDouble(parts[1]) == 0.) {
+ continue;
+ }
+
+ double value = Double.parseDouble(parts[1]);
+
+ nonZeroLinks.put(parts[0], value);
+ }
+ } finally {
+
+ }
+
+ Assertions.assertFalse(nonZeroLinks.isEmpty());
+ Assertions.assertTrue(nonZeroLinks.containsKey("28922425#0"));
+ Assertions.assertTrue(nonZeroLinks.containsKey("-686055693#1"));
+ Assertions.assertEquals(71.21, Math.round(nonZeroLinks.get("28922425#0") * 100.) / 100. , 0.001);
+ Assertions.assertEquals(69.72, Math.round(nonZeroLinks.get("-686055693#1") * 100.) / 100., 0.001);
+ }
+
+ private void createTestPopulation(Path inputPath) {
+ Population population = PopulationUtils.createPopulation(config);
+ PopulationFactory fac = population.getFactory();
+ Person person = fac.createPerson(carPersonId);
+ Plan plan = PopulationUtils.createPlan(person);
+
+// home in hoyerswerda, nearest link 28922425#0
+ Activity home = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24));
+ home.setEndTime(8 * 3600);
+ Activity home2 = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24));
+ home2.setEndTime(19 * 3600);
+// work in hoyerswerda, nearest link(s): 686055693#1, -686055693#1
+ Activity work = fac.createActivityFromCoord("work_2400", new Coord(863866.47,5710961.86));
+ work.setEndTime(17 * 3600 + 25 * 60);
+
+ Leg leg = fac.createLeg(TransportMode.car);
+
+ plan.addActivity(home);
+ plan.addLeg(leg);
+ plan.addActivity(work);
+ plan.addLeg(leg);
+ plan.addActivity(home2);
+
+ person.addPlan(plan);
+ PersonUtils.setIncome(person, 1000.);
+ person.getAttributes().putAttribute("subpopulation", "person");
+ population.addPerson(person);
+
+ new PopulationWriter(population).write(inputPath.toString());
+ }
+}
diff --git a/src/test/java/org/matsim/run/RunIntegrationTest.java b/src/test/java/org/matsim/run/RunIntegrationTest.java
index 30e2941..085cfaa 100644
--- a/src/test/java/org/matsim/run/RunIntegrationTest.java
+++ b/src/test/java/org/matsim/run/RunIntegrationTest.java
@@ -1,6 +1,5 @@
package org.matsim.run;
-import com.univocity.parsers.common.input.EOFException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -13,9 +12,7 @@
import org.matsim.api.core.v01.events.handler.PersonEntersVehicleEventHandler;
import org.matsim.api.core.v01.network.Network;
import org.matsim.api.core.v01.population.*;
-import org.matsim.application.ApplicationUtils;
import org.matsim.application.MATSimApplication;
-import org.matsim.application.options.CsvOptions;
import org.matsim.core.api.experimental.events.EventsManager;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
@@ -27,12 +24,8 @@
import org.matsim.pt.transitSchedule.api.*;
import org.matsim.simwrapper.SimWrapperConfigGroup;
import org.matsim.testcases.MatsimTestUtils;
-import tech.tablesaw.api.ColumnType;
-import tech.tablesaw.api.DoubleColumn;
-import tech.tablesaw.api.Table;
-import tech.tablesaw.io.csv.CsvReadOptions;
-import java.io.IOException;
+import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
@@ -59,7 +52,11 @@ void runScenario() {
"--iterations", "1",
"--config:plans.inputPlansFile", "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/lausitz/input/v1.1/lausitz-v1.1-1pct.plans-initial.xml.gz",
"--output", utils.getOutputDirectory(),
- "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code";
+ "--config:controller.overwriteFiles=deleteDirectoryIfExists", "--emissions", "DO_NOT_PERFORM_EMISSIONS_ANALYSIS")
+ == 0 : "Must return non error code";
+
+ Assertions.assertTrue(new File(utils.getOutputDirectory()).isDirectory());
+ Assertions.assertTrue(new File(utils.getOutputDirectory()).exists());
}
@Test
@@ -67,35 +64,16 @@ void runScenarioIncludingDrt() {
Config config = ConfigUtils.loadConfig(String.format("input/v%s/lausitz-v%s-10pct.config.xml", LausitzScenario.VERSION, LausitzScenario.VERSION));
ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class).defaultDashboards = SimWrapperConfigGroup.Mode.disabled;
- Path inputPath = p.resolve("drt-test-population.xml.gz");
-
- createTestPopulation(config, inputPath, TransportMode.drt, new Coord(838300.95,5711890.36));
-
assert MATSimApplication.execute(RunLausitzDrtScenario.class, config,
"--1pct",
"--iterations", "1",
- "--config:plans.inputPlansFile", inputPath.toString(),
+ "--config:plans.inputPlansFile", "https://svn.vsp.tu-berlin.de/repos/public-svn/matsim/scenarios/countries/de/lausitz/input/v1.1/lausitz-v1.1-1pct.plans-initial.xml.gz",
"--output", utils.getOutputDirectory(),
- "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code";
-
- //read customer stats
- Path customerStatsPath = ApplicationUtils.matchInput("drt_customer_stats_" + TransportMode.drt + ".csv", Path.of(utils.getOutputDirectory()));
- try {
- Table customerStats = Table.read()
- .csv(CsvReadOptions.builder(customerStatsPath.toFile())
- .columnTypes(columnHeader -> columnHeader.equals("runId") ? ColumnType.STRING : ColumnType.DOUBLE)
- .separator(CsvOptions.detectDelimiter(customerStatsPath.toString()))
- .build());
-
- Assertions.assertEquals(2, customerStats.rowCount());
-
- DoubleColumn rideCol = customerStats.doubleColumn("rides");
+ "--config:controller.overwriteFiles=deleteDirectoryIfExists", "--emissions", "DO_NOT_PERFORM_EMISSIONS_ANALYSIS")
+ == 0 : "Must return non error code";
-// there should be exactly 2 drt rides
- Assertions.assertEquals(2, rideCol.get(rideCol.size() - 1));
- } catch (IOException e) {
- throw new EOFException();
- }
+ Assertions.assertTrue(new File(utils.getOutputDirectory()).isDirectory());
+ Assertions.assertTrue(new File(utils.getOutputDirectory()).exists());
}
@Test
@@ -105,14 +83,45 @@ void runScenarioIncludingAdditionalPtLine() {
Path inputPath = p.resolve("pt-test-population.xml.gz");
- createTestPopulation(config, inputPath, TransportMode.pt, new Coord(867489.48,5746587.47));
+ Population population = PopulationUtils.createPopulation(config);
+ PopulationFactory fac = population.getFactory();
+ Person person = fac.createPerson(ptPersonId);
+ Plan plan = PopulationUtils.createPlan(person);
+
+// home in hoyerswerda
+ Activity home = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24));
+ home.setEndTime(8 * 3600);
+ Activity home2 = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24));
+ home2.setEndTime(19 * 3600);
+// work in cottbus
+ Activity work = fac.createActivityFromCoord("work_2400", new Coord(867489.48,5746587.47));
+ work.setEndTime(17 * 3600 + 25 * 60);
+
+ Leg leg = fac.createLeg(TransportMode.pt);
+
+ plan.addActivity(home);
+ plan.addLeg(leg);
+ plan.addActivity(work);
+ plan.addLeg(leg);
+ plan.addActivity(home2);
+
+ person.addPlan(plan);
+ PersonUtils.setIncome(person, 1000.);
+ person.getAttributes().putAttribute("subpopulation", "person");
+ population.addPerson(person);
+
+ new PopulationWriter(population).write(inputPath.toString());
assert MATSimApplication.execute(RunLausitzPtScenario.class, config,
"--1pct",
"--iterations", "1",
"--output", utils.getOutputDirectory(),
"--config:plans.inputPlansFile", inputPath.toString(),
- "--config:controller.overwriteFiles=deleteDirectoryIfExists") == 0 : "Must return non error code";
+ "--config:controller.overwriteFiles=deleteDirectoryIfExists", "--emissions", "DO_NOT_PERFORM_EMISSIONS_ANALYSIS")
+ == 0 : "Must return non error code";
+
+ Assertions.assertTrue(new File(utils.getOutputDirectory()).isDirectory());
+ Assertions.assertTrue(new File(utils.getOutputDirectory()).exists());
Scenario scenario = ScenarioUtils.createScenario(ConfigUtils.createConfig());
@@ -140,37 +149,6 @@ void runScenarioIncludingAdditionalPtLine() {
}
- private static void createTestPopulation(Config config, Path inputPath, String mode, Coord workLocation) {
- Population population = PopulationUtils.createPopulation(config);
- PopulationFactory fac = population.getFactory();
- Person person = fac.createPerson(ptPersonId);
- Plan plan = PopulationUtils.createPlan(person);
-
-// home in hoyerswerda
- Activity home = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24));
- home.setEndTime(8 * 3600);
- Activity home2 = fac.createActivityFromCoord("home_2400", new Coord(863538.13,5711028.24));
- home2.setEndTime(19 * 3600);
-// work in given location
- Activity work = fac.createActivityFromCoord("work_2400", workLocation);
- work.setEndTime(17 * 3600 + 25 * 60);
-
- Leg leg = fac.createLeg(mode);
-
- plan.addActivity(home);
- plan.addLeg(leg);
- plan.addActivity(work);
- plan.addLeg(leg);
- plan.addActivity(home2);
-
- person.addPlan(plan);
- PersonUtils.setIncome(person, 1000.);
- person.getAttributes().putAttribute("subpopulation", "person");
- population.addPerson(person);
-
- new PopulationWriter(population).write(inputPath.toString());
- }
-
private static final class PersonEntersPtVehicleEventHandler implements PersonEntersVehicleEventHandler {
static List enterEvents = new ArrayList<>();