Skip to content

Commit

Permalink
Merge branch 'master' into bicycleContrib
Browse files Browse the repository at this point in the history
  • Loading branch information
tschlenther authored Aug 1, 2024
2 parents 7b0e554 + 33d857b commit d5df451
Show file tree
Hide file tree
Showing 195 changed files with 3,026 additions and 2,022 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private void runCommand(Class<? extends MATSimAppCommand> clazz, Path input) thr
MATSimAppCommand command = clazz.getDeclaredConstructor().newInstance();
String[] args = this.args.get(clazz);
args = ArrayUtils.addAll(args, createArgs(clazz, args, input));
log.info("Running {} with arguments: {}", clazz, Arrays.toString(args));
log.info("Running {} with arguments: {}", clazz, String.join(" ", args));

command.execute(args);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,11 @@ private void writeOutput(Network network, EmissionsOnLinkEventHandler emissionsE
if (link2pollutants.get(linkId).get(pollutant) != null) {
emissionValue = link2pollutants.get(linkId).get(pollutant);
}
absolute.print(nf.format(emissionValue));
absolute.print(nf.format(emissionValue * sample.getUpscaleFactor()));

Link link = network.getLinks().get(linkId);
double emissionPerM = emissionValue / link.getLength();
perMeter.print(nf.format(emissionPerM));
perMeter.print(nf.format(emissionPerM * sample.getUpscaleFactor()));
}

absolute.println();
Expand Down Expand Up @@ -246,7 +246,7 @@ private void writeTotal(Network network, EmissionsOnLinkEventHandler emissionsEv

total.printRecord("Pollutant", "kg");
for (Pollutant p : Pollutant.values()) {
double val = (sum.getDouble(p) / sample.getSample()) / 1000;
double val = (sum.getDouble(p) * sample.getUpscaleFactor()) / 1000;
total.printRecord(p, val < 100_000 && val > 100 ? simple.format(val) : scientific.format(val));
}

Expand Down Expand Up @@ -286,7 +286,7 @@ private void writeAvroRaster(Network network, Config config, EmissionsOnLinkEven
for (int xi = 0; xi < xLength.get(0); xi++) {
for (int yi = 0; yi < yLength.get(0); yi++) {
Coord coord = raster.getCoordForIndex(xi, yi);
double value = rasterMap.get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi);
double value = rasterMap.get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi) * sample.getUpscaleFactor();
if (xi == 0) yCoords.add((float) coord.getY());
if (yi == 0) xCoords.add((float) coord.getX());
valuesList.add((float) value);
Expand Down Expand Up @@ -349,7 +349,7 @@ private void writeRaster(Network network, Config config, EmissionsOnLinkEventHan
for (int yi = 0; yi < yLength.get(0); yi++) {

Coord coord = raster.getCoordForIndex(xi, yi);
double value = rasterMap.get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi);
double value = rasterMap.get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi) * sample.getUpscaleFactor();

if (value == 0)
continue;
Expand Down Expand Up @@ -406,7 +406,7 @@ private void writeTimeDependentRaster(Network network, Config config, EmissionsO
for (TimeBinMap.TimeBin<Map<Pollutant, Raster>> timeBin : timeBinMap.getTimeBins()) {

Coord coord = raster.getCoordForIndex(xi, yi);
double value = timeBin.getValue().get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi);
double value = timeBin.getValue().get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi) * sample.getUpscaleFactor();

if (value == 0)
continue;
Expand Down Expand Up @@ -467,7 +467,8 @@ private void writeTimeDependentAvroRaster(Network network, Config config, Emissi
if (yi == 0 && isFirst)
xCoords.add((float) coord.getX());

valuesList.add((float) timeBin.getValue().get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi));
double value = timeBin.getValue().get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi) * sample.getUpscaleFactor();
valuesList.add((float) value);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.math3.analysis.interpolation.LoessInterpolator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.locationtech.jts.geom.Coordinate;
Expand All @@ -32,6 +33,7 @@
import java.math.RoundingMode;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.IntStream;

import static tech.tablesaw.aggregate.AggregateFunctions.count;

Expand All @@ -41,6 +43,7 @@
produces = {
"mode_share.csv", "mode_share_per_dist.csv", "mode_users.csv", "trip_stats.csv",
"mode_share_per_%s.csv", "population_trip_stats.csv", "trip_purposes_by_hour.csv",
"mode_share_distance_distribution.csv",
"mode_choices.csv", "mode_choice_evaluation.csv", "mode_choice_evaluation_per_mode.csv",
"mode_confusion_matrix.csv", "mode_prediction_error.csv"
}
Expand Down Expand Up @@ -109,6 +112,25 @@ private static int durationToSeconds(String d) {
return (Integer.parseInt(split[0]) * 60 * 60) + (Integer.parseInt(split[1]) * 60) + Integer.parseInt(split[2]);
}

private static double[] calcHistogram(double[] data, double[] bins) {

double[] hist = new double[bins.length - 1];

for (int i = 0; i < bins.length - 1; i++) {

double binStart = bins[i];
double binEnd = bins[i + 1];

// The last right bin edge is inclusive, which is consistent with the numpy implementation
if (i == bins.length - 2)
hist[i] = Arrays.stream(data).filter(d -> d >= binStart && d <= binEnd).count();
else
hist[i] = Arrays.stream(data).filter(d -> d >= binStart && d < binEnd).count();
}

return hist;
}

@Override
public Integer call() throws Exception {

Expand Down Expand Up @@ -247,6 +269,8 @@ public Integer call() throws Exception {

writeTripPurposes(joined);

writeTripDistribution(joined);

return 0;
}

Expand Down Expand Up @@ -293,13 +317,15 @@ private void writeTripStats(Table trips) throws IOException {
Object2IntMap<String> n = new Object2IntLinkedOpenHashMap<>();
Object2LongMap<String> travelTime = new Object2LongOpenHashMap<>();
Object2LongMap<String> travelDistance = new Object2LongOpenHashMap<>();
Object2LongMap<String> beelineDistance = new Object2LongOpenHashMap<>();

for (Row trip : trips) {
String mainMode = trip.getString("main_mode");

n.mergeInt(mainMode, 1, Integer::sum);
travelTime.mergeLong(mainMode, durationToSeconds(trip.getString("trav_time")), Long::sum);
travelDistance.mergeLong(mainMode, trip.getLong("traveled_distance"), Long::sum);
beelineDistance.mergeLong(mainMode, trip.getLong("euclidean_distance"), Long::sum);
}

try (CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(output.getPath("trip_stats.csv")), CSVFormat.DEFAULT)) {
Expand Down Expand Up @@ -338,6 +364,13 @@ private void writeTripStats(Table trips) throws IOException {
}
printer.println();

printer.print("Avg. beeline speed [km/h]");
for (String m : modeOrder) {
double speed = (beelineDistance.getLong(m) / 1000d) / (travelTime.getLong(m) / (60d * 60d));
printer.print(new BigDecimal(speed).setScale(2, RoundingMode.HALF_UP));
}
printer.println();

printer.print("Avg. distance per trip [km]");
for (String m : modeOrder) {
double avg = (travelDistance.getLong(m) / 1000d) / (n.getInt(m));
Expand Down Expand Up @@ -458,6 +491,55 @@ private void writeTripPurposes(Table trips) {

}

private void writeTripDistribution(Table trips) throws IOException {

Map<String, double[]> dists = new LinkedHashMap<>();

// Note that the results of this interpolator are consistent with the one performed in matsim-python-tools
// This makes the results comparable with reference data, changes here will also require changes in the python package
LoessInterpolator inp = new LoessInterpolator(0.05, 0);

long max = distGroups.get(distGroups.size() - 3) + distGroups.get(distGroups.size() - 2);

double[] bins = IntStream.range(0, (int) (max / 100)).mapToDouble(i -> i * 100).toArray();
double[] x = Arrays.copyOf(bins, bins.length - 1);

for (String mode : modeOrder) {
double[] distances = trips.where(
trips.stringColumn("main_mode").equalsIgnoreCase(mode))
.numberColumn("traveled_distance").asDoubleArray();

double[] hist = calcHistogram(distances, bins);

double[] y = inp.smooth(x, hist);
dists.put(mode, y);
}

try (CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(output.getPath("mode_share_distance_distribution.csv")), CSVFormat.DEFAULT)) {

printer.print("dist");
for (String s : modeOrder) {
printer.print(s);
}
printer.println();

for (int i = 0; i < x.length; i++) {

double sum = 0;
for (String s : modeOrder) {
sum += Math.max(0, dists.get(s)[i]);
}

printer.print(x[i]);
for (String s : modeOrder) {
double value = Math.max(0, dists.get(s)[i]) / sum;
printer.print(value);
}
printer.println();
}
}
}

/**
* How shape file filtering should be applied.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ final class TripByGroupAnalysis {
}
}

// Norm shares per instance of each group to sum of 1
for (Group group : this.groups) {

String norm = group.columns.get(0);
if (group.columns.size() > 1)
throw new UnsupportedOperationException("Multiple columns not supported yet");

Table df = group.data;
for (String label : df.stringColumn(norm).asSet()) {
DoubleColumn dist_group = df.doubleColumn("share");
Selection sel = df.stringColumn(norm).isEqualTo(label);
double total = dist_group.where(sel).sum();
if (total > 0)
dist_group.set(sel, dist_group.divide(total));
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

/**
* Class to calculate the traffic congestion index based on the paper
* "A Traffic Congestion Assessment Method for Urban Road Networks Based on Speed Performance Index" by Feifei He, Xuedong Yan*, Yang Liu, Lu Ma.
* "A Traffic Congestion Assessment Method for Urban Road Networks Based on Speed Performance Index" by Feifei He, Xuedong Yan, Yang Liu, Lu Ma.
*/
public final class TrafficStatsCalculator {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ public double getSample() {
return sample;
}

/**
* Return factor that is used to upscale the sample size.
*/
public double getUpscaleFactor() {
return 1.0 / sample;
}

private void setSize(double sample) {
this.set = true;
this.sample = sample;
Expand Down
Loading

0 comments on commit d5df451

Please sign in to comment.