Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

debug analysis required for dashboards #82

Merged
merged 17 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<artifactId>matsim-all</artifactId>

<!-- PR-labelled release -->
<version>2025.0-PR3271</version>
<version>2025.0-PR3328</version>

<!-- snapshot == not recommended: rather use PR-labelled release!-->
<!-- <version>16.0-SNAPSHOT</matsim.version>-->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.time.LocalTime;
import java.util.*;

Expand All @@ -25,11 +27,7 @@
@CommandLine.Command(name = "average-drt", description = "Calculates average drt stats based on several sim runs with different random seeds.")
@CommandSpec(
requires = {"runs", "mode"},
produces = {"rides_per_veh_avg_demand_stats.csv", "avg_wait_time_avg_demand_stats.csv", "requests_avg_demand_stats.csv", "avg_total_travel_time_avg_demand_stats.csv",
"rides_avg_demand_stats.csv", "avg_direct_distance_[km]_avg_demand_stats.csv", "rejections_avg_demand_stats.csv", "95th_percentile_wait_time_avg_demand_stats.csv",
"avg_in-vehicle_time_avg_demand_stats.csv", "avg_ride_distance_[km]_avg_demand_stats.csv", "rejection_rate_avg_demand_stats.csv",
"avg_fare_[MoneyUnit]_avg_demand_stats.csv", "total_service_hours_avg_supply_stats.csv", "pooling_ratio_avg_supply_stats.csv", "detour_ratio_avg_supply_stats.csv",
"total_vehicle_mileage_[km]_avg_supply_stats.csv", "empty_ratio_avg_supply_stats.csv", "number_of_stops_avg_supply_stats.csv", "total_pax_distance_[km]_avg_supply_stats.csv", "vehicles_avg_supply_stats.csv"}
produces = {"avg_demand_stats.csv", "avg_supply_stats.csv"}
)
public class DrtPostProcessingAverageAnalysis implements MATSimAppCommand {

Expand All @@ -44,7 +42,6 @@ public class DrtPostProcessingAverageAnalysis implements MATSimAppCommand {
private final Map<String, List<Double>> supplyStats = new HashMap<>();
private final Map<String, Double[]> demandAvgs = new HashMap<>();
private final Map<String, Double[]> supplyAvgs = new HashMap<>();
Map<String, List<String>> params = new HashMap<>();

private final CsvOptions csv = new CsvOptions();

Expand All @@ -70,11 +67,11 @@ public Integer call() throws Exception {

Table demand = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(demandKpiCsv))
.sample(false)
.separator(csv.detectDelimiter(demandKpiCsv)).build());
.separator(CsvOptions.detectDelimiter(demandKpiCsv)).build());

Table supply = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(supplyKpiCsv))
.sample(false)
.separator(csv.detectDelimiter(supplyKpiCsv)).build());
.separator(CsvOptions.detectDelimiter(supplyKpiCsv)).build());

// get all demand stats
for (int i = 0; i < demand.rowCount(); i++) {
Expand Down Expand Up @@ -113,38 +110,30 @@ public Integer call() throws Exception {
fillAvgMap(demandStats, demandAvgs);
fillAvgMap(supplyStats, supplyAvgs);

params.put("avg_demand_stats.csv", List.of("rides_per_veh", "avg_wait_time", "requests", "avg_total_travel_time", "rides", "avg_direct_distance_[km]",
"rejections", "95th_percentile_wait_time", "avg_in-vehicle_time", "avg_ride_distance_[km]", "rejection_rate", "avg_fare_[MoneyUnit]"));
params.put("avg_supply_stats.csv", List.of("total_service_hours", "pooling_ratio", "detour_ratio", "total_vehicle_mileage_[km]", "empty_ratio", "number_of_stops",
"total_pax_distance_[km]", "vehicles"));
// ordered list of params to display them in same order as in single-run DrtDashboard
List<String> orderedDemandParams = List.of("Handled Requests", "Passengers (Pax)", "Avg Group Size", "Pax per veh", "Pax per veh-h", "Pax per veh-km",
"Rejections", "Rejection rate", "Avg. total travel time", "Avg. in-vehicle time", "Avg. wait time", "95th percentile wait time", "Avg. ride distance [km]",
"Avg. direct distance [km]", "Avg. fare [MoneyUnit]");
List<String> orderedSupplyParams = List.of("Number of stops", "Vehicles", "Total vehicle mileage [km]", "Empty ratio", "Total pax distance [km]",
"Occupancy rate [pax-km/v-km]", "Detour ratio", "Total service hours");

for (Map.Entry<String, List<String>> e : params.entrySet()) {
for (String param : params.get(e.getKey())) {
if (e.getKey().contains("demand")) {
writeFile(e.getKey(), demandAvgs, param);
} else {
writeFile(e.getKey(), supplyAvgs, param);
}
}
}
writeFile("avg_demand_stats.csv", demandAvgs, orderedDemandParams);
writeFile("avg_supply_stats.csv", supplyAvgs, orderedSupplyParams);

return 0;
}

private void writeFile(String fileName, Map<String, Double[]> values, String param) throws IOException {
try (CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(output.getPath(param + "_" + fileName)), CSVFormat.DEFAULT)) {
private void writeFile(String fileName, Map<String, Double[]> values, List<String> orderedParams) throws IOException {
try (CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(output.getPath(fileName)), CSVFormat.DEFAULT)) {
DecimalFormat df = new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.US));

printer.printRecord("info", value);
// as of 19.06.24 min and max values are not printed anymore. they will still be calculated though.
// if one wants to include them to dashboard tables one just has to re-include them in this print method. -sme0624
printer.printRecord("parameter", "mean", "median", "standard deviation");

for (Map.Entry<String, Double[]> e : values.entrySet()) {
String transformed = e.getKey().toLowerCase().replace(".", "").replace(" ", "_");
if (transformed.contains(param)) {
printer.printRecord("mean-" + e.getKey(), e.getValue()[0]);
printer.printRecord("median-" + e.getKey(), e.getValue()[1]);
printer.printRecord("sd-" + e.getKey(), e.getValue()[2]);
printer.printRecord("min-" + e.getKey(), e.getValue()[3]);
printer.printRecord("max-" + e.getKey(), e.getValue()[4]);
}

for (String param : orderedParams) {
printer.printRecord(param, df.format(values.get(param)[0]), df.format(values.get(param)[1]), df.format(values.get(param)[2]));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.apache.commons.math3.util.Precision;
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.matsim.analysis.postAnalysis.traffic.TrafficAnalysis;
import org.matsim.api.core.v01.Coord;
Expand Down Expand Up @@ -35,7 +36,6 @@
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.VehicleType;
import org.matsim.vehicles.VehicleUtils;
import org.opengis.feature.simple.SimpleFeature;
import picocli.CommandLine;

import java.io.FileWriter;
Expand Down
136 changes: 7 additions & 129 deletions src/main/java/org/matsim/dashboard/AverageDrtDashboard.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,142 +39,20 @@ public void configure(Header header, Layout layout) {
header.description = "Overview for the demand-responsive mode '" + mode + "'. This dashboard shows average values for " + noRuns +
" simulation runs. For the results of the specific runs please choose the according directory next to this dashboard.yaml.";

// DEMAND
layout.row("one")
.el(Table.class, (viz, data) -> {
viz.title = "Rides per vehicle";
viz.dataset = postProcess(data, "rides_per_veh_avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
.el(Table.class, (viz, data) -> {
viz.title = "Avg wait time";
viz.dataset = postProcess(data, "avg_wait_time_avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
.el(Table.class, (viz, data) -> {
viz.title = "Requests";
viz.dataset = postProcess(data, "requests_avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
});

layout.row("two")
.el(Table.class, (viz, data) -> {
viz.title = "Avg total travel time";
viz.dataset = postProcess(data, "avg_total_travel_time_avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
.el(Table.class, (viz, data) -> {
viz.title = "Rides";
viz.dataset = postProcess(data, "rides_avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
.el(Table.class, (viz, data) -> {
viz.title = "Avg direct distance [km]";
viz.dataset = postProcess(data, "avg_direct_distance_[km]_avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
});

layout.row("three")
.el(Table.class, (viz, data) -> {
viz.title = "Rejections";
viz.dataset = postProcess(data, "rejections_avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
.el(Table.class, (viz, data) -> {
viz.title = "95th percentile wait time";
viz.dataset = postProcess(data, "95th_percentile_wait_time_avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
.el(Table.class, (viz, data) -> {
viz.title = "Avg in-vehicle time";
viz.dataset = postProcess(data, "avg_in-vehicle_time_avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
});

layout.row("four")
.el(Table.class, (viz, data) -> {
viz.title = "Avg ride distance [km]";
viz.dataset = postProcess(data, "avg_ride_distance_[km]_avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
.el(Table.class, (viz, data) -> {
viz.title = "Rejection rate";
viz.dataset = postProcess(data, "rejection_rate_avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
.el(Table.class, (viz, data) -> {
viz.title = "Avg fare [MoneyUnit]";
viz.dataset = postProcess(data, "avg_fare_[MoneyUnit]_avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
});

// SUPPLY
supplyTabs(layout);
}

private void supplyTabs(Layout layout) {
layout.row("six")
layout.row("supply")
.el(Table.class, (viz, data) -> {
viz.title = "Total service hours";
viz.dataset = postProcess(data, "total_service_hours_avg_supply_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
.el(Table.class, (viz, data) -> {
viz.title = "Pooling ratio";
viz.dataset = postProcess(data, "pooling_ratio_avg_supply_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
.el(Table.class, (viz, data) -> {
viz.title = "Detour ratio";
viz.dataset = postProcess(data, "detour_ratio_avg_supply_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
});

layout.row("seven")
.el(Table.class, (viz, data) -> {
viz.title = "Total vehicle mileage [km]";
viz.dataset = postProcess(data, "total_vehicle_mileage_[km]_avg_supply_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
.el(Table.class, (viz, data) -> {
viz.title = "Empty ratio";
viz.dataset = postProcess(data, "empty_ratio_avg_supply_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
.el(Table.class, (viz, data) -> {
viz.title = "Number of stops";
viz.dataset = postProcess(data, "number_of_stops_avg_supply_stats.csv");
viz.title = "Service summary";
viz.dataset = postProcess(data, "avg_supply_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
});

layout.row("eight")
.el(Table.class, (viz, data) -> {
viz.title = "Total pax distance [km]";
viz.dataset = postProcess(data, "total_pax_distance_[km]_avg_supply_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
})
// DEMAND
layout.row("demand")
.el(Table.class, (viz, data) -> {
viz.title = "Vehicles";
viz.dataset = postProcess(data, "vehicles_avg_supply_stats.csv");
viz.title = "Demand summary";
viz.dataset = postProcess(data, "avg_demand_stats.csv");
viz.showAllRows = true;
viz.width = 1.;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
/**
* class to create average dashboards and run the necessary analysis for that.
*/
public class CreateAverageDashboards implements MATSimAppCommand {
final class CreateAverageDashboards implements MATSimAppCommand {
@CommandLine.Option(names = "--input-path", required = true, description = "Path to directory with run directories.")
private String inputPath;
@CommandLine.Option(names = "--no-runs", defaultValue = "5", description = "Number of simulation runs to be averaged.")
Expand Down Expand Up @@ -62,7 +62,7 @@ public Integer call() throws Exception {

Arrays.stream(new File(analysisDir).listFiles())
.filter(d -> d.getAbsolutePath().contains(TransportMode.drt))
.forEach(f -> modes.add(f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf("\\") + 1)));
.forEach(f -> modes.add(f.getName()));

SimWrapper sw = SimWrapper.create();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import org.matsim.simwrapper.Dashboard;
import org.matsim.simwrapper.DashboardProvider;
import org.matsim.simwrapper.SimWrapper;
import org.matsim.simwrapper.dashboard.NoiseDashboard;
import org.matsim.simwrapper.dashboard.TravelTimeComparisonDashboard;
import org.matsim.simwrapper.dashboard.TripDashboard;

Expand All @@ -27,8 +26,9 @@ public List<Dashboard> getDashboards(Config config, SimWrapper simWrapper) {
return List.of(
trips,
new TravelTimeComparisonDashboard(IOUtils.resolveFileOrResource( "kelheim-v3.0-routes-ref.csv.gz").toString()),
new KelheimEmissionsDashboard(),
new NoiseDashboard()
new KelheimEmissionsDashboard()
//the NoiseAnalysis needs more RAM than the entire simulation, which leads to VM crashes and prevents other analysis to run. We have to run it separately (e.g. with KelheimSimWrapperRunner)
// new NoiseDashboard()
);
}

Expand Down
Loading
Loading