Skip to content

Commit

Permalink
Merge pull request #2151 from LBNL-UCB-STI/inm/fix-not-updating-in-re…
Browse files Browse the repository at this point in the history
…al-time-config-values-2

Inm/fix not updating in real time config values 2
  • Loading branch information
wrashid authored Oct 30, 2019
2 parents 221fb7a + ee2a05d commit 6f29113
Show file tree
Hide file tree
Showing 22 changed files with 274 additions and 65 deletions.
21 changes: 15 additions & 6 deletions src/main/java/beam/analysis/via/ExpectedMaxUtilityHeatMap.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package beam.analysis.via;

import beam.agentsim.events.ModeChoiceEvent;
import beam.sim.BeamServices;
import beam.sim.config.BeamConfig;
import beam.utils.NetworkHelper;
import org.matsim.api.core.v01.events.Event;
import org.matsim.api.core.v01.network.Link;
Expand All @@ -15,18 +17,24 @@
public class ExpectedMaxUtilityHeatMap implements BasicEventHandler {

private final String SEPERATOR = ",";
private final NetworkHelper networkHelper;
private final OutputDirectoryHierarchy controlerIO;
private final int writeEventsInterval;
private CSVWriter csvWriter;
static final String fileBaseName = "expectedMaxUtilityHeatMap";
private BufferedWriter bufferedWriter;
private boolean writeDataInThisIteration = false;
private BeamServices beamServices;

public ExpectedMaxUtilityHeatMap(EventsManager eventsManager, NetworkHelper networkHelper, OutputDirectoryHierarchy controlerIO, int writeEventsInterval) {
this.networkHelper = networkHelper;
private NetworkHelper networkHelper() {
return beamServices.networkHelper();
}

private int writeEventsInterval() {
return beamServices.beamConfig().beam().outputs().writeEventsInterval();
}

public ExpectedMaxUtilityHeatMap(EventsManager eventsManager, BeamServices beamServices, OutputDirectoryHierarchy controlerIO) {
this.controlerIO = controlerIO;
this.writeEventsInterval = writeEventsInterval;
this.beamServices = beamServices;
eventsManager.addHandler(this);
}

Expand All @@ -35,7 +43,7 @@ public void handleEvent(Event event) {
if (writeDataInThisIteration && event instanceof ModeChoiceEvent) {
ModeChoiceEvent modeChoiceEvent = (ModeChoiceEvent) event;
int linkId = Integer.parseInt(modeChoiceEvent.location);
Link link = networkHelper.getLinkUnsafe(linkId);
Link link = networkHelper().getLinkUnsafe(linkId);

if (link != null) { // TODO: fix this, so that location of mode choice event is always initialized
try {
Expand All @@ -61,6 +69,7 @@ public void reset(int iteration) {
this.csvWriter.closeFile();
}

int writeEventsInterval = writeEventsInterval();
writeDataInThisIteration = writeEventsInterval > 0 && iteration % writeEventsInterval == 0;

if (writeDataInThisIteration) {
Expand Down
76 changes: 76 additions & 0 deletions src/main/java/beam/matsim/CustomPlansDumpingImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package beam.matsim;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.apache.log4j.Logger;
import org.matsim.analysis.IterationStopWatch;
import org.matsim.api.core.v01.network.Network;
import org.matsim.api.core.v01.population.Population;
import org.matsim.api.core.v01.population.PopulationWriter;
import org.matsim.core.config.Config;
import org.matsim.core.config.groups.ControlerConfigGroup;
import org.matsim.core.controler.OutputDirectoryHierarchy;
import org.matsim.core.controler.corelisteners.PlansDumping;
import org.matsim.core.controler.events.BeforeMobsimEvent;
import org.matsim.core.controler.listener.BeforeMobsimListener;
import org.matsim.core.utils.geometry.CoordinateTransformation;
import org.matsim.core.utils.geometry.transformations.TransformationFactory;

@Singleton
public class CustomPlansDumpingImpl implements PlansDumping, BeforeMobsimListener {
static final private Logger log = Logger.getLogger(CustomPlansDumpingImpl.class);

@Inject
private Config config;
@Inject
private Network network;
@Inject
private Population population;
@Inject
private IterationStopWatch stopwatch;
@Inject
private OutputDirectoryHierarchy controlerIO;
@Inject
private ControlerConfigGroup controlerConfigGroup;

private int writePlansInterval() {
return controlerConfigGroup.getWritePlansInterval();
}

private int writeMoreUntilIteration() {
return controlerConfigGroup.getWritePlansUntilIteration();
}

@Inject
CustomPlansDumpingImpl() {
}

@Override
public void notifyBeforeMobsim(final BeforeMobsimEvent event) {
final boolean writingPlansAtAll = writePlansInterval() > 0;
final boolean regularWritePlans = writePlansInterval() > 0 && (event.getIteration() > 0 && event.getIteration() % writePlansInterval() == 0);
final boolean earlyIteration = event.getIteration() <= writeMoreUntilIteration();
if (writingPlansAtAll && (regularWritePlans || earlyIteration)) {
stopwatch.beginOperation("dump all plans");
log.info("dumping plans...");
final String inputCRS = config.plans().getInputCRS();
final String internalCRS = config.global().getCoordinateSystem();

if (inputCRS == null) {
new PopulationWriter(population, network).write(controlerIO.getIterationFilename(event.getIteration(), "plans.xml.gz"));
} else {
log.info("re-projecting population from " + internalCRS + " back to " + inputCRS + " for export");

final CoordinateTransformation transformation =
TransformationFactory.getCoordinateTransformation(
internalCRS,
inputCRS);

new PopulationWriter(transformation, population, network).write(controlerIO.getIterationFilename(event.getIteration(), "plans.xml.gz"));
}
log.info("finished plans dump.");
stopwatch.endOperation("dump all plans");
}
}

}
39 changes: 39 additions & 0 deletions src/main/java/beam/matsim/MatsimConfigUpdater.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package beam.matsim;

import beam.sim.BeamConfigChangesObservable;
import beam.sim.config.BeamConfig;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.matsim.core.config.groups.ControlerConfigGroup;
import org.matsim.core.config.groups.LinkStatsConfigGroup;
import scala.Tuple2;

import java.util.Observable;
import java.util.Observer;

@Singleton
public class MatsimConfigUpdater implements Observer {
private ControlerConfigGroup controlerConfigGroup;
private LinkStatsConfigGroup linkStatsConfigGroup;

@Inject
MatsimConfigUpdater(BeamConfigChangesObservable beamConfigChangesObservable, LinkStatsConfigGroup linkStatsConfigGroup, ControlerConfigGroup controlerConfigGroup) {
this.controlerConfigGroup = controlerConfigGroup;
this.linkStatsConfigGroup = linkStatsConfigGroup;

beamConfigChangesObservable.addObserver(this);
}

@Override
public void update(Observable observable, Object o) {
if (o instanceof Tuple2) {
Tuple2 t = (Tuple2) o;
if (t._2 instanceof BeamConfig) {
BeamConfig beamConfig = (BeamConfig) t._2;

controlerConfigGroup.setWritePlansInterval(beamConfig.beam().physsim().writePlansInterval());
linkStatsConfigGroup.setWriteLinkStatsInterval(beamConfig.matsim().modules().linkStats().writeLinkStatsInterval());
}
}
}
}
4 changes: 4 additions & 0 deletions src/main/resources/beam-template.conf
Original file line number Diff line number Diff line change
Expand Up @@ -742,5 +742,9 @@ matsim.modules {
}
]
}
linkStats {
writeLinkStatsInterval = "int | 10"
averageLinkStatsOverIterations = "int | 5"
}
}

24 changes: 16 additions & 8 deletions src/main/scala/beam/router/BeamSkimmer.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package beam.router

import java.io.File
import java.util.concurrent.TimeUnit

import beam.agentsim.agents.choice.mode.DrivingCost
import beam.agentsim.agents.vehicles.{BeamVehicle, BeamVehicleType}
Expand All @@ -22,13 +21,13 @@ import beam.router.Modes.BeamMode.{
}
import beam.router.model.{BeamLeg, BeamPath, EmbodiedBeamTrip}
import beam.sim.common.GeoUtils
import beam.sim.config.BeamConfig
import beam.sim.vehiclesharing.VehicleManager
import beam.sim.{BeamScenario, BeamServices, BeamWarmStart}
import beam.sim.{BeamScenario, BeamServices}
import beam.utils.{FileUtils, ProfilingUtils}
import com.typesafe.scalalogging.LazyLogging
import javax.inject.Inject
import org.matsim.api.core.v01.{Coord, Id}
import org.matsim.core.config.groups.TravelTimeCalculatorConfigGroup
import org.matsim.core.controler.events.IterationEndsEvent
import org.matsim.core.utils.io.IOUtils
import org.supercsv.io.CsvMapReader
Expand All @@ -40,18 +39,21 @@ import scala.util.control.NonFatal

//TODO to be validated against google api
class BeamSkimmer @Inject()(
val beamServices: BeamServices,
val beamScenario: BeamScenario,
val geo: GeoUtils
) extends LazyLogging {
import BeamSkimmer._
import beamScenario._

def beamConfig: BeamConfig = beamServices.beamConfig

// The OD/Mode/Time Matrix
private var previousSkims: BeamSkimmerADT = initialPreviousSkims()
private var skims: BeamSkimmerADT = TrieMap()

private def skimsFilePath: Option[String] = {
val filePath = beamScenario.beamConfig.beam.warmStart.skimsFilePath
val filePath = beamConfig.beam.warmStart.skimsFilePath
if (new File(filePath).isFile) {
Some(filePath)
} else {
Expand Down Expand Up @@ -385,7 +387,7 @@ class BeamSkimmer @Inject()(
BeamSkimmer.excerptSkimsFileBaseName + ".csv.gz"
)
val dummyId = Id.create(
beamScenario.beamConfig.beam.agentsim.agents.rideHail.initialization.procedural.vehicleTypeId,
beamConfig.beam.agentsim.agents.rideHail.initialization.procedural.vehicleTypeId,
classOf[BeamVehicleType]
)
val writer = IOUtils.getBufferedWriter(filePath)
Expand Down Expand Up @@ -444,7 +446,7 @@ class BeamSkimmer @Inject()(
val uniqueTimeBins = 0 to 23

val dummyId = Id.create(
beamScenario.beamConfig.beam.agentsim.agents.rideHail.initialization.procedural.vehicleTypeId,
beamConfig.beam.agentsim.agents.rideHail.initialization.procedural.vehicleTypeId,
classOf[BeamVehicleType]
)

Expand Down Expand Up @@ -513,7 +515,7 @@ class BeamSkimmer @Inject()(
initialPreviousSkimsPlus()
private var skimsPlus: TrieMap[BeamSkimmerPlusKey, Double] = TrieMap()
private def skimsPlusFilePath: Option[String] = {
val filePath = beamScenario.beamConfig.beam.warmStart.skimsPlusFilePath
val filePath = beamConfig.beam.warmStart.skimsPlusFilePath
if (new File(filePath).isFile) {
Some(filePath)
} else {
Expand Down Expand Up @@ -561,7 +563,13 @@ class BeamSkimmer @Inject()(
skimsPlus.put(key, skimsPlus.getOrElse(key, 0.0) + count.toDouble)
}

def addValue(curBin: Int, tazId: Id[TAZ], vehicleManager: Id[VehicleManager], label: Label, value: Double) = {
def addValue(
curBin: Int,
tazId: Id[TAZ],
vehicleManager: Id[VehicleManager],
label: Label,
value: Double
): Option[Double] = {
if (curBin > trackSkimsPlusTS) trackSkimsPlusTS = curBin
val key = (trackSkimsPlusTS, tazId, vehicleManager, label)
skimsPlus.put(key, skimsPlus.getOrElse(key, 0.0) + value)
Expand Down
7 changes: 4 additions & 3 deletions src/main/scala/beam/router/TravelTimeObserved.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import beam.analysis.plots.{GraphUtils, GraphsStatsAgentSimEventsListener}
import beam.router.Modes.BeamMode
import beam.router.Modes.BeamMode.{CAR, WALK}
import beam.router.model.{EmbodiedBeamLeg, EmbodiedBeamTrip}
import beam.sim.BeamScenario
import beam.sim.{BeamScenario, BeamServices}
import beam.sim.common.GeoUtils
import beam.utils.{FileUtils, GeoJsonReader, ProfilingUtils}
import com.google.inject.Inject
Expand All @@ -31,14 +31,15 @@ import org.supercsv.prefs.CsvPreference
import scala.collection.mutable

class TravelTimeObserved @Inject()(
val beamServices: BeamServices,
val beamScenario: BeamScenario,
val geo: GeoUtils
) extends LazyLogging {
import TravelTimeObserved._
import beamScenario._

@volatile
private var skimmer: BeamSkimmer = new BeamSkimmer(beamScenario, geo)
private var skimmer: BeamSkimmer = new BeamSkimmer(beamServices, beamScenario, geo)

private val observedTravelTimesOpt: Option[Map[PathCache, Float]] = {
val zoneBoundariesFilePath = beamConfig.beam.calibration.roadNetwork.travelTimes.zoneBoundariesFilePath
Expand Down Expand Up @@ -99,7 +100,7 @@ class TravelTimeObserved @Inject()(

def notifyIterationEnds(event: IterationEndsEvent): Unit = {
writeTravelTimeObservedVsSimulated(event)
skimmer = new BeamSkimmer(beamScenario, geo)
skimmer = new BeamSkimmer(beamServices, beamScenario, geo)
}

def writeTravelTimeObservedVsSimulated(event: IterationEndsEvent): Unit = {
Expand Down
10 changes: 9 additions & 1 deletion src/main/scala/beam/sim/BeamHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import beam.agentsim.events.handling.BeamEventsHandling
import beam.agentsim.infrastructure.taz.TAZTreeMap
import beam.analysis.ActivityLocationPlotter
import beam.analysis.plots.{GraphSurgePricing, RideHailRevenueAnalysis}
import beam.matsim.{CustomPlansDumpingImpl, MatsimConfigUpdater}
import beam.replanning._
import beam.replanning.utilitybased.UtilityBasedModeChoice
import beam.router._
Expand Down Expand Up @@ -44,7 +45,7 @@ import org.matsim.core.api.experimental.events.EventsManager
import org.matsim.core.config.groups.TravelTimeCalculatorConfigGroup
import org.matsim.core.config.{Config => MatsimConfig}
import org.matsim.core.controler._
import org.matsim.core.controler.corelisteners.{ControlerDefaultCoreListenersModule, EventsHandling}
import org.matsim.core.controler.corelisteners.{ControlerDefaultCoreListenersModule, EventsHandling, PlansDumping}
import org.matsim.core.scenario.{MutableScenario, ScenarioBuilder, ScenarioByInstanceModule, ScenarioUtils}
import org.matsim.core.trafficmonitoring.TravelTimeCalculator
import org.matsim.households.Household
Expand Down Expand Up @@ -153,7 +154,14 @@ trait BeamHelper extends LazyLogging {
bind(classOf[BeamConfigHolder])
val beamConfigChangesObservable = new BeamConfigChangesObservable(beamConfig)

bind(classOf[MatsimConfigUpdater]).asEagerSingleton()

bind(classOf[PlansDumping]).to(classOf[CustomPlansDumpingImpl])

bind(classOf[BeamConfigChangesObservable]).toInstance(beamConfigChangesObservable)

bind(classOf[TerminationCriterion]).to(classOf[CustomTerminateAtFixedIterationNumber])

bind(classOf[PrepareForSim]).to(classOf[BeamPrepareForSim])
bind(classOf[RideHailSurgePricingManager]).asEagerSingleton()

Expand Down
5 changes: 2 additions & 3 deletions src/main/scala/beam/sim/BeamSim.scala
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,8 @@ class BeamSim @Inject()(
modalityStyleStats = new ModalityStyleStats()
expectedDisutilityHeatMapDataCollector = new ExpectedMaxUtilityHeatMap(
eventsManager,
beamServices.networkHelper,
event.getServices.getControlerIO,
beamServices.beamConfig.beam.outputs.writeEventsInterval
beamServices,
event.getServices.getControlerIO
)

tncIterationsStatsCollector = new RideHailIterationsStatsCollector(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package beam.sim

import beam.sim.config.BeamConfigHolder
import javax.inject.Inject
import org.matsim.core.config.groups.ControlerConfigGroup
import org.matsim.core.controler.TerminationCriterion

class CustomTerminateAtFixedIterationNumber extends TerminationCriterion {
private var lastIteration = 0
private var beamConfigHolder: BeamConfigHolder = _

@Inject
def this(controlerConfigGroup: ControlerConfigGroup, beamConfigHolder: BeamConfigHolder) {
this()
this.beamConfigHolder = beamConfigHolder
this.lastIteration = controlerConfigGroup.getLastIteration
}

override def continueIterations(iteration: Int): Boolean = {
lastIteration = beamConfigHolder.beamConfig.beam.agentsim.lastIteration
iteration <= lastIteration
}

}
Loading

0 comments on commit 6f29113

Please sign in to comment.