Skip to content

Commit

Permalink
Merge branch 'refs/heads/master' into modifyFreightDemandGenerationTool
Browse files Browse the repository at this point in the history
  • Loading branch information
rewertvsp committed Jun 21, 2024
2 parents a127fee + b9ab343 commit 17bf445
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ public Integer call() throws Exception {
private Config prepareConfig() {
Config config = ConfigUtils.loadConfig(ApplicationUtils.matchInput("config.xml", input.getRunDirectory()).toAbsolutePath().toString(), new NoiseConfigGroup());

//it is important to match "output_vehicles" because otherwise dvrpVehicle files might be matched and the code crashes later
config.vehicles().setVehiclesFile(ApplicationUtils.matchInput("output_vehicles", input.getRunDirectory()).toAbsolutePath().toString());
//it is important to match "output_vehicles.xml.gz" specifically, because otherwise dvrpVehicle files might be matched and the code crashes later
config.vehicles().setVehiclesFile(ApplicationUtils.matchInput("output_vehicles.xml.gz", input.getRunDirectory()).toAbsolutePath().toString());
config.network().setInputFile(ApplicationUtils.matchInput("network", input.getRunDirectory()).toAbsolutePath().toString());
config.transit().setTransitScheduleFile(null);
config.transit().setVehiclesFile(null);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* *********************************************************************** *
* project: org.matsim.*
* Controler.java
* *
* *********************************************************************** *
* *
* copyright : (C) 2007 by the members listed in the COPYING, *
* LICENSE and WARRANTY file. *
* email : info at matsim dot org *
* *
* *********************************************************************** *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* See also COPYING, LICENSE and WARRANTY file *
* *
* *********************************************************************** */

package org.matsim.contrib.drt.extension.dashboards;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.application.ApplicationUtils;
import org.matsim.application.MATSimAppCommand;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.simwrapper.SimWrapper;
import org.matsim.simwrapper.SimWrapperConfigGroup;
import picocli.CommandLine;

import java.io.IOException;
import java.nio.file.Path;
import java.util.List;

@CommandLine.Command(
name = "drt",
description = "Run DRT analysis and create SimWrapper dashboard for existing run output."
)
final class CreateDrtDashboard implements MATSimAppCommand {

private static final Logger log = LogManager.getLogger(CreateDrtDashboard.class);

@CommandLine.Parameters(arity = "1..*", description = "Path to run output directories for which DRT dashboards are to be generated.")
private List<Path> inputPaths;

private CreateDrtDashboard(){
}

@Override
public Integer call() throws Exception {

for (Path runDirectory : inputPaths) {
log.info("Running on {}", runDirectory);

Path configPath = ApplicationUtils.matchInput("config.xml", runDirectory);
Config config = ConfigUtils.loadConfig(configPath.toString());
SimWrapper sw = SimWrapper.create(config);

SimWrapperConfigGroup simwrapperCfg = ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class);

//skip default dashboards
simwrapperCfg.defaultDashboards = SimWrapperConfigGroup.Mode.disabled;

//add drt dashboards
new DrtDashboardProvider().getDashboards(config, sw).forEach(sw::addDashboard);

try {
//append dashboard to existing ones
boolean append = true;
sw.generate(runDirectory, append);
sw.run(runDirectory);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

return 0;
}

public static void main(String[] args) {
new CreateDrtDashboard().execute(args);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ private static Table prepareSupplyKPITable(Table vehicleStats) {
.round()
.setName("Total pax distance [km]"));

tableSupplyKPI.column("d_p/d_t").setName("Pooling ratio");
tableSupplyKPI.column("d_p/d_t").setName("Occupancy rate [pax-km/v-km]");
tableSupplyKPI.column("l_det").setName("Detour ratio");
tableSupplyKPI.column("emptyRatio").setName("Empty ratio");

Expand All @@ -122,17 +122,19 @@ private static void printDemandKPICSV(Table customerStats, Table tableSupplyKPI,
double rides = getLastDoubleValue(customerStats, "rides");
double rejections = getLastDoubleValue(customerStats, "rejections");
double requests = rides + rejections;
double pax = getLastDoubleValue(customerStats, "rides_pax");

DecimalFormat df = new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.US));

try (CSVPrinter csv = new CSVPrinter(Files.newBufferedWriter(output), CSVFormat.DEFAULT)) {
csv.printRecord("Info", "value");

csv.printRecord("Requests", requests);
csv.printRecord("Rides", rides);
csv.printRecord("Rides per veh", df.format(rides / ((DoubleColumn) tableSupplyKPI.column("vehicles")).get(0)));
csv.printRecord("Rides per veh-h", df.format(rides / ((DoubleColumn) tableSupplyKPI.column("total service hours")).get(0)));
csv.printRecord("Rides per veh-km", df.format(rides / ((DoubleColumn) tableSupplyKPI.column("total vehicle mileage [km]")).get(0)));
csv.printRecord("Handled Requests", requests);
csv.printRecord("Passengers (Pax)", pax);
csv.printRecord("Avg Group Size", df.format((getLastDoubleValue(customerStats, "groupSize_mean"))));
csv.printRecord("Pax per veh", df.format(pax / ((DoubleColumn) tableSupplyKPI.column("vehicles")).get(0)));
csv.printRecord("Pax per veh-h", df.format(pax / ((DoubleColumn) tableSupplyKPI.column("total service hours")).get(0)));
csv.printRecord("Pax per veh-km", df.format(pax / ((DoubleColumn) tableSupplyKPI.column("total vehicle mileage [km]")).get(0)));
csv.printRecord("Rejections", rejections);
csv.printRecord("Rejection rate", getLastDoubleValue(customerStats, "rejectionRate"));
csv.printRecord("Avg. total travel time", LocalTime.ofSecondOfDay(getLastDoubleValue(customerStats, "totalTravelTime_mean").longValue()));
Expand Down Expand Up @@ -168,28 +170,13 @@ public Integer call() throws Exception {
//read vehicle stats
Path vehicleStatsPath = ApplicationUtils.matchInput("drt_vehicle_stats_" + drtMode + ".csv", input.getRunDirectory());
Table vehicleStats = Table.read().csv(CsvReadOptions.builder(vehicleStatsPath.toFile())
.columnTypesPartial(Map.of("vehicles", ColumnType.DOUBLE,
"totalDistance", ColumnType.DOUBLE,
"emptyRatio", ColumnType.DOUBLE,
"totalServiceDuration", ColumnType.DOUBLE,
"d_p/d_t", ColumnType.DOUBLE,
"totalPassengerDistanceTraveled", ColumnType.DOUBLE))
.columnTypes(columnHeader -> columnHeader.equals("runId") ? ColumnType.STRING : ColumnType.DOUBLE)
.separator(';').build());

//read customer stats
Path customerStatsPath = ApplicationUtils.matchInput("drt_customer_stats_" + drtMode + ".csv", input.getRunDirectory());
Table customerStats = Table.read().csv(CsvReadOptions.builder(customerStatsPath.toFile())
.columnTypesPartial(Map.of(
"rides", ColumnType.DOUBLE,
"wait_average", ColumnType.DOUBLE,
"wait_p95", ColumnType.DOUBLE,
"inVehicleTravelTime_mean", ColumnType.DOUBLE,
"distance_m_mean", ColumnType.DOUBLE,
"directDistance_m_mean", ColumnType.DOUBLE,
"totalTravelTime_mean", ColumnType.DOUBLE,
"fareAllReferences_mean", ColumnType.DOUBLE,
"rejections", ColumnType.DOUBLE,
"rejectionRate", ColumnType.DOUBLE))
.columnTypes(columnHeader -> columnHeader.equals("runId") ? ColumnType.STRING : ColumnType.DOUBLE)
.separator(';').build());

Table tableSupplyKPI = Table.create("supplyKPI");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ public void configure(Header header, Layout layout) {
.el(Line.class, (viz, data) -> {
viz.title = "Relative Statistics per iteration";
viz.dataset = data.output("*vehicle_stats_" + drtConfigGroup.mode + ".csv");
viz.description = "Pooling ratio (Pax distance / Vehicle mileage), Detour ratio, and Empty Ratio";
viz.description = "Occupancy rate (Pax distance / Vehicle mileage), Detour ratio, and Empty Ratio";
viz.x = "iteration";
viz.columns = List.of("d_p/d_t", "l_det", "emptyRatio");
viz.legendName = List.of("Pooling ratio", "Detour ratio", "Empty Ratio");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.matsim.simwrapper.dashboard;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.matsim.application.MATSimApplication;
Expand All @@ -15,6 +16,7 @@


import java.net.URL;
import java.nio.file.Path;

public class NoiseDashboardTests {

Expand All @@ -24,6 +26,8 @@ public class NoiseDashboardTests {

@Test
void generate() {
Path out = Path.of(utils.getOutputDirectory(), "analysis", "noise");

Config config = TestScenario.loadConfig(utils);

config.global().setCoordinateSystem("EPSG:25832");
Expand All @@ -34,11 +38,14 @@ void generate() {

simWrapperConfigGroup.defaultParams().shp = IOUtils.extendUrl(kelheim, "area/area.shp").toString();


SimWrapper sw = SimWrapper.create(config).addDashboard(new NoiseDashboard());
Controler controler = MATSimApplication.prepare(new TestScenario(sw), config);


controler.run();

Assertions.assertThat(out)
.isDirectoryContaining("glob:**emission_per_day.csv")
.isDirectoryContaining("glob:**immission_per_day.avro")
.isDirectoryContaining("glob:**immission_per_hour.avro");
}
}

0 comments on commit 17bf445

Please sign in to comment.