Skip to content

Commit

Permalink
Refactoring: 30 small improvements/fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
carloscaldas authored Mar 31, 2020
2 parents 8d45fc6 + 42e8044 commit 9bc107e
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 66 deletions.
83 changes: 35 additions & 48 deletions src/main/java/beam/analysis/physsim/PhyssimCalcLinkSpeedStats.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;
Expand All @@ -32,53 +33,48 @@
*/
public class PhyssimCalcLinkSpeedStats {

private static final List<Color> colors = new ArrayList<>();
private static int noOfBins = 24;
private static int binSize = 3600;
static final String OUTPUT_FILE_NAME = "physsimLinkAverageSpeedPercentage";
private static final int BIN_SIZE = 3600;
private static final List<Color> COLORS = Collections.unmodifiableList(
Arrays.asList(Color.GREEN, Color.BLUE)
);
private static final int NUM_OF_BIN_TEST_MODE = 24;

// Static initialization of colors
static {
colors.add(Color.GREEN);
colors.add(Color.BLUE);
}

private BeamConfig beamConfig;
private Network network;
private OutputDirectoryHierarchy outputDirectoryHierarchy;
static String outputFileName = "physsimLinkAverageSpeedPercentage";
private final int numOfBins;
private final BeamConfig beamConfig;
private final Network network;
private final OutputDirectoryHierarchy outputDirectoryHierarchy;

//Public constructor for the PhyssimCalcLinkSpeedStats class
public PhyssimCalcLinkSpeedStats(Network network, OutputDirectoryHierarchy outputDirectoryHierarchy, BeamConfig beamConfig) {
this.network = network;
this.outputDirectoryHierarchy = outputDirectoryHierarchy;
this.beamConfig = beamConfig;

// If not test mode pick up bin count from the beam configuration.
if (isNotTestMode()) {
Double endTime = Time.parseTime(beamConfig.matsim().modules().qsim().endTime());
Double noOfTimeBins = endTime / this.beamConfig.beam().physsim().linkStatsBinSize();
noOfTimeBins = Math.floor(noOfTimeBins);
noOfBins = noOfTimeBins.intValue() + 1;
}
numOfBins = isTestMode()
? NUM_OF_BIN_TEST_MODE
: getNumOfBinsFromConfig(beamConfig);
}

private int getNumOfBinsFromConfig(BeamConfig beamConfig) {
double endTime = Time.parseTime(beamConfig.matsim().modules().qsim().endTime());
Double numOfTimeBins = endTime / this.beamConfig.beam().physsim().linkStatsBinSize();
numOfTimeBins = Math.floor(numOfTimeBins);
return numOfTimeBins.intValue() + 1;
}

// implement the iteration start notification class
public void notifyIterationEnds(int iteration, TravelTimeCalculator travelTimeCalculator) {
Map<Integer, Double> processedData = generateInputDataForGraph(travelTimeCalculator);
CategoryDataset dataSet = generateGraphCategoryDataSet(processedData);
if (this.outputDirectoryHierarchy != null) {
//If not running in test mode , write output to a csv file
if (isNotTestMode()) {
this.writeCSV(processedData, outputDirectoryHierarchy.getIterationFilename(iteration, outputFileName + ".csv"));
if (!isTestMode()) {
this.writeCSV(processedData, outputDirectoryHierarchy.getIterationFilename(iteration, OUTPUT_FILE_NAME + ".csv"));
}
//generate the requiredGraph
if (beamConfig.beam().outputs().writeGraphs()) {
generateAverageLinkSpeedGraph(dataSet, iteration);
}
}
}

// helper method to write output to a csv file
private void writeCSV(Map<Integer, Double> processedData, String path) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(path));
Expand All @@ -94,23 +90,21 @@ private void writeCSV(Map<Integer, Double> processedData, String path) {
}
}

// A helper method to test if the application is running in test mode or not
private boolean isNotTestMode() {
return beamConfig != null;
private boolean isTestMode() {
return beamConfig == null;
}

// generate the data required as input to generate a graph
private Map<Integer, Double> generateInputDataForGraph(TravelTimeCalculator travelTimeCalculator) {
TravelTime travelTime = travelTimeCalculator.getLinkTravelTimes();

return IntStream.range(0, noOfBins).parallel().boxed()
return IntStream.range(0, numOfBins).parallel().boxed()
.collect(Collectors.toMap(Function.identity(),
idx -> calcLinkAvgSpeedPercentage(travelTime, idx)));
}

private double calcLinkAvgSpeedPercentage(TravelTime travelTime, int idx) {
List<Double> avgSpeeds = this.network.getLinks().values().parallelStream()
.filter(link -> IntStream.range(0, noOfBins).parallel() // filter links with average speed >= freeSpeed
.filter(link -> IntStream.range(0, numOfBins).parallel() // filter links with average speed >= freeSpeed
.anyMatch(i -> calcSpeedRatio(i, link, travelTime) >= 1))
.map(link -> calcSpeedRatio(idx, link, travelTime))
.collect(Collectors.toList());
Expand All @@ -119,22 +113,20 @@ private double calcLinkAvgSpeedPercentage(TravelTime travelTime, int idx) {

private double calcSpeedRatio(int idx, Link link, TravelTime travelTime) {

double freeSpeed = link.getFreespeed(idx * binSize);
double freeSpeed = link.getFreespeed(idx * BIN_SIZE);
double linkLength = link.getLength();
double averageTime = travelTime.getLinkTravelTime(link, idx * binSize, null, null);
double averageTime = travelTime.getLinkTravelTime(link, idx * BIN_SIZE, null, null);
double averageSpeed = linkLength / averageTime;
return averageSpeed / freeSpeed;
}

//create the Category Data set
private CategoryDataset generateGraphCategoryDataSet(Map<Integer, Double> processedData) {
double[][] dataSet = buildDataSetFromProcessedData(processedData);
return DatasetUtilities.createCategoryDataset("Relative Speed", "", dataSet);
}

//build a matrix data set from the processed Data
private double[][] buildDataSetFromProcessedData(Map<Integer, Double> processedData) {
double[][] dataSet = new double[100][noOfBins];
double[][] dataSet = new double[100][numOfBins];
for (int i = 0; i < processedData.size(); i++) {
dataSet[0][i] = processedData.get(i);
}
Expand All @@ -149,15 +141,12 @@ private void generateAverageLinkSpeedGraph(CategoryDataset dataSet, int iteratio
int width = 800;
int height = 600;

// Setting orientation for the ploteStackedBarChart
PlotOrientation orientation = PlotOrientation.VERTICAL;

// Create the chart
final JFreeChart chart = ChartFactory
.createStackedBarChart(plotTitle, x_axis, y_axis, dataSet, orientation, false, true, true);
chart.setBackgroundPaint(new Color(255, 255, 255));

//Get the category plot from the chart
CategoryPlot plot = chart.getCategoryPlot();

//add the sorted frequencies to the legend
Expand All @@ -166,7 +155,7 @@ private void generateAverageLinkSpeedGraph(CategoryDataset dataSet, int iteratio
plot.getRenderer().setSeriesPaint(0, getColor(0));
plot.setFixedLegendItems(legendItems);
//Save the chart as image
String graphImageFile = outputDirectoryHierarchy.getIterationFilename(iterationNumber, outputFileName + ".png");
String graphImageFile = outputDirectoryHierarchy.getIterationFilename(iterationNumber, OUTPUT_FILE_NAME + ".png");
try {
ChartUtilities.saveChartAsPNG(new File(graphImageFile), chart, width,
height);
Expand All @@ -176,15 +165,14 @@ private void generateAverageLinkSpeedGraph(CategoryDataset dataSet, int iteratio
}

private Color getColor(int i) {
if (i < colors.size()) {
return colors.get(i);
if (i < COLORS.size()) {
return COLORS.get(i);
} else {
return getRandomColor();
}
}

private Color getRandomColor() {

Random rand = new Random();

float r = rand.nextFloat();
Expand All @@ -194,7 +182,6 @@ private Color getRandomColor() {
return new Color(r, g, b);
}


public double getAverageSpeedPercentageOfBin(int bin, TravelTimeCalculator travelTimeCalculator) {
try {
Map<Integer, Double> processedData = generateInputDataForGraph(travelTimeCalculator);
Expand All @@ -214,6 +201,6 @@ public double[] getAverageSpeedPercentagesOfAllBins(TravelTimeCalculator travelT
}

public int getNumberOfBins() {
return noOfBins;
return numOfBins;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ object PhyssimCalcLinkSpeedStatsObject extends OutputDataDescriptor {
*/
def getOutputDataDescriptions: util.List[OutputDataDescription] = {
val freeSpeedDistOutputFilePath: String = GraphsStatsAgentSimEventsListener.CONTROLLER_IO
.getIterationFilename(0, PhyssimCalcLinkSpeedStats.outputFileName + ".csv")
.getIterationFilename(0, PhyssimCalcLinkSpeedStats.OUTPUT_FILE_NAME + ".csv")
val outputDirPath: String = GraphsStatsAgentSimEventsListener.CONTROLLER_IO.getOutputPath
val freeSpeedDistRelativePath: String = freeSpeedDistOutputFilePath.replace(outputDirPath, "")
val list: util.List[OutputDataDescription] = new util.ArrayList[OutputDataDescription]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,40 @@
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.Event;
import scala.collection.Set;
import scala.collection.Set$;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class VehicleMilesTraveledAnalysis implements IterationSummaryAnalysis {
private Map<String, Double> milesTraveledByVehicleType = new HashMap<>();
private Set<Id<BeamVehicleType>> vehicleTypes;
private String humanBodyVehicleType = "BODY-TYPE-DEFAULT";
private final double meterToMileConverterConst = 0.000621371192; // unit conversion from meters to miles

private static final String HUMAN_BODY_VEHICLE_TYPE = "BODY-TYPE-DEFAULT";
private static final double METER_TO_MILE_CONVERTER_CONST = 0.000621371192D;

private final Map<String, Double> milesTraveledByVehicleType = new HashMap<>();
private final Set<Id<BeamVehicleType>> vehicleTypes;

public VehicleMilesTraveledAnalysis(Set<Id<BeamVehicleType>> vehicleTypes) {
this.vehicleTypes = vehicleTypes;
this.vehicleTypes = vehicleTypes == null
? Set$.MODULE$.empty()
: vehicleTypes;
}

@Override
public void processStats(Event event) {
if (event instanceof PathTraversalEvent) {
PathTraversalEvent pte = (PathTraversalEvent)event;
PathTraversalEvent pte = (PathTraversalEvent) event;
String vehicleType = pte.vehicleType();
double lengthInMeters = pte.legLength();

if (!vehicleType.equalsIgnoreCase(humanBodyVehicleType)) {
milesTraveledByVehicleType.merge(vehicleType, lengthInMeters, (d1, d2) -> d1 + d2);
milesTraveledByVehicleType.merge("total", lengthInMeters, (d1, d2) -> d1 + d2);
if (!vehicleType.equalsIgnoreCase(HUMAN_BODY_VEHICLE_TYPE)) {
milesTraveledByVehicleType.merge(vehicleType, lengthInMeters, Double::sum);
milesTraveledByVehicleType.merge("total", lengthInMeters, Double::sum);
}

}
}

@Override
public void resetStats() {
milesTraveledByVehicleType.clear();
Expand All @@ -44,10 +49,10 @@ public void resetStats() {
public Map<String, Double> getSummaryStats() {
Map<String, Double> result = milesTraveledByVehicleType.entrySet().stream().collect(Collectors.toMap(
e -> "motorizedVehicleMilesTraveled_" + e.getKey(),
e -> e.getValue() * meterToMileConverterConst
e -> e.getValue() * METER_TO_MILE_CONVERTER_CONST
));

vehicleTypes.foreach(vt -> result.put("vehicleMilesTraveled_" + vt.toString(), milesTraveledByVehicleType.getOrDefault(vt.toString(), 0.0) * meterToMileConverterConst));
vehicleTypes.foreach(vt -> result.put("vehicleMilesTraveled_" + vt.toString(), milesTraveledByVehicleType.getOrDefault(vt.toString(), 0.0) * METER_TO_MILE_CONVERTER_CONST));

return result;
}
Expand Down
8 changes: 3 additions & 5 deletions src/main/java/beam/physsim/jdeqsim/cacc/sim/Road.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

public class Road extends org.matsim.core.mobsim.jdeqsim.Road {

private final double INCREASE_TIMESTAMP = 0.0000000001;
private static final double INCREASE_TIMESTAMP = 0.0000000001D;
private static RoadCapacityAdjustmentFunction roadCapacityAdjustmentFunction;
private HashMap<Vehicle,Double> caccShareEncounteredByVehicle=new HashMap<>();
private double speedAdjustmentFactor;
Expand Down Expand Up @@ -172,7 +172,7 @@ private double getNextAvailableTimeForLeavingStreet(double simTime){
public void procsessFilledRoad(org.matsim.core.mobsim.jdeqsim.Vehicle vehicle, double simTime) {
LinkedList<Double> gap = getGap();
if (gap == null) {
gap = new LinkedList<>();
setGap(new LinkedList<>());
} else {
gap.clear();
}
Expand All @@ -184,11 +184,9 @@ public void procsessFilledRoad(org.matsim.core.mobsim.jdeqsim.Vehicle vehicle, d
* 'stuckTime' the car behind has to wait an additional stuckTime
* (this logic was adapted to adhere to the C++ implementation)
*/
double nextStuckTime=0;

double nextStuckTime;
if (getDeadlockPreventionMessages().size() > 0) {
nextStuckTime= getDeadlockPreventionMessages().getLast().getMessageArrivalTime() + config.getSqueezeTime();

} else {
nextStuckTime=simTime + config.getSqueezeTime();
}
Expand Down

0 comments on commit 9bc107e

Please sign in to comment.