From 68b36ec31c5739f3f528406ec7a43e6ae947ca54 Mon Sep 17 00:00:00 2001 From: Alvin Lee Jin Wen Date: Fri, 26 Aug 2022 22:39:44 +0800 Subject: [PATCH 1/5] Reads from csv file, skips vehicleAdjustment(No-Op), generates beam vehicles from vehicleInfo and binds to household Able to run with: gradle :run -PappArgs="['--config', 'test/input/beamville/beam-urbansimv2-static.conf']" Config difference: beam.agentsim.agents.vehicles.vehiclesFilePath = ${beam.inputDirectory}"/vehicles-test.csv" beam.agentsim.agents.vehicles.vehicleAdjustmentMethod = "STATIC_FROM_FILE" --- .../sim/vehicles/NoOpVehiclesAdjustment.scala | 30 ++ .../sim/vehicles/VehiclesAdjustment.scala | 2 + .../scenario/UrbanSimScenarioLoader.scala | 62 ++- .../beamville/beam-urbansimv2-static.conf | 375 ++++++++++++++++++ test/input/beamville/vehicles-test.csv | 3 + 5 files changed, 468 insertions(+), 4 deletions(-) create mode 100644 src/main/scala/beam/sim/vehicles/NoOpVehiclesAdjustment.scala create mode 100755 test/input/beamville/beam-urbansimv2-static.conf create mode 100644 test/input/beamville/vehicles-test.csv diff --git a/src/main/scala/beam/sim/vehicles/NoOpVehiclesAdjustment.scala b/src/main/scala/beam/sim/vehicles/NoOpVehiclesAdjustment.scala new file mode 100644 index 00000000000..adfed18b852 --- /dev/null +++ b/src/main/scala/beam/sim/vehicles/NoOpVehiclesAdjustment.scala @@ -0,0 +1,30 @@ +package beam.sim.vehicles + +import beam.agentsim.agents.Population +import beam.agentsim.agents.vehicles.VehicleCategory.VehicleCategory +import beam.agentsim.agents.vehicles.{BeamVehicleType, VehicleCategory} +import beam.sim.BeamScenario +import org.apache.commons.math3.distribution.UniformRealDistribution +import org.matsim.api.core.v01.Coord + +case class NoOpVehiclesAdjustment(beamScenario: BeamScenario) extends VehiclesAdjustment { + override def sampleVehicleTypesForHousehold( + numVehicles: Int, + vehicleCategory: VehicleCategory, + householdIncome: Double, + householdSize: Int, + householdPopulation: Population, + householdLocation: Coord, + realDistribution: UniformRealDistribution + ): List[BeamVehicleType] = { + List() + } + + override def sampleVehicleTypes( + numVehicles: Int, + vehicleCategory: VehicleCategory, + realDistribution: UniformRealDistribution + ): List[BeamVehicleType] = { + List() + } +} diff --git a/src/main/scala/beam/sim/vehicles/VehiclesAdjustment.scala b/src/main/scala/beam/sim/vehicles/VehiclesAdjustment.scala index 3dbe5efacb4..5bbc3f83b6e 100644 --- a/src/main/scala/beam/sim/vehicles/VehiclesAdjustment.scala +++ b/src/main/scala/beam/sim/vehicles/VehiclesAdjustment.scala @@ -31,10 +31,12 @@ trait VehiclesAdjustment extends ExponentialLazyLogging { object VehiclesAdjustment { val UNIFORM_ADJUSTMENT = "UNIFORM" val INCOME_BASED_ADJUSTMENT = "INCOME_BASED" + val STATIC_FROM_FILE = "STATIC_FROM_FILE" def getVehicleAdjustment(beamScenario: BeamScenario): VehiclesAdjustment = { beamScenario.beamConfig.beam.agentsim.agents.vehicles.vehicleAdjustmentMethod match { case UNIFORM_ADJUSTMENT => UniformVehiclesAdjustment(beamScenario) + case STATIC_FROM_FILE => NoOpVehiclesAdjustment(beamScenario) case INCOME_BASED_ADJUSTMENT => IncomeBasedVehiclesAdjustment(beamScenario) case _ => UniformVehiclesAdjustment(beamScenario) } diff --git a/src/main/scala/beam/utils/scenario/UrbanSimScenarioLoader.scala b/src/main/scala/beam/utils/scenario/UrbanSimScenarioLoader.scala index b4394c789f4..5177c878b42 100644 --- a/src/main/scala/beam/utils/scenario/UrbanSimScenarioLoader.scala +++ b/src/main/scala/beam/utils/scenario/UrbanSimScenarioLoader.scala @@ -1,13 +1,16 @@ package beam.utils.scenario import beam.agentsim.agents.vehicles.EnergyEconomyAttributes.Powertrain -import beam.agentsim.agents.vehicles.{BeamVehicle, VehicleCategory} +import beam.agentsim.agents.vehicles.{BeamVehicle, BeamVehicleType, VehicleCategory, VehicleManager} import beam.router.Modes.BeamMode import beam.sim.BeamScenario import beam.sim.common.GeoUtils import beam.sim.vehicles.VehiclesAdjustment +import beam.sim.vehicles.VehiclesAdjustment.STATIC_FROM_FILE import beam.utils.SequenceUtils +import beam.utils.csv.readers import beam.utils.plan.sampling.AvailableModeUtils +import beam.utils.scenario.BeamScenarioLoader.buildBeamVehicle import beam.utils.scenario.urbansim.HOVModeTransformer import com.typesafe.scalalogging.LazyLogging import org.apache.commons.math3.distribution.UniformRealDistribution @@ -18,9 +21,10 @@ import org.matsim.core.scenario.MutableScenario import org.matsim.households._ import org.matsim.vehicles.{Vehicle, VehicleType, VehicleUtils} +import java.util.concurrent.atomic.AtomicReference import scala.collection.JavaConverters._ import scala.collection.mutable.ArrayBuffer -import scala.collection.{mutable, Iterable} +import scala.collection.{Iterable, mutable} import scala.concurrent.duration._ import scala.concurrent.{Await, ExecutionContext, Future} import scala.math.{max, min, round} @@ -57,6 +61,14 @@ class UrbanSimScenarioLoader( def loadScenario(): (Scenario, Boolean) = { clear() +// for { +// vehicleInfo <- vehicles +// vehicle = buildBeamVehicle(beamScenario.vehicleTypes, vehicleInfo, rand.nextInt) +// } { +// beamScenario.privateVehicles.put(vehicle.id, vehicle) +// vehicleInfo.initialSoc.foreach(beamScenario.privateVehicleInitialSoc.put(vehicle.id, _)) +// } + val plansF = Future { val plans = scenarioSource.getPlans logger.info(s"Read ${plans.size} plans") @@ -123,7 +135,6 @@ class UrbanSimScenarioLoader( scenario.getPopulation.getPersonAttributes.clear() scenario.getHouseholds.getHouseholds.clear() scenario.getHouseholds.getHouseholdAttributes.clear() - beamScenario.privateVehicles.clear() beamScenario.privateVehicleInitialSoc.clear() } @@ -168,7 +179,8 @@ class UrbanSimScenarioLoader( .find(_.vehicleCategory == VehicleCategory.Bike) .getOrElse(throw new RuntimeException("Bike not found in vehicle types.")) - assignVehicles(households, householdIdToPersons, personId2Score).foreach { case (householdInfo, nVehicles) => + assignVehicles(households, householdIdToPersons, personId2Score).foreach { + case (householdInfo, nVehicles) => val id = Id.create(householdInfo.householdId.id, classOf[Household]) val household = new HouseholdsFactoryImpl().createHousehold(id) val coord = utmCoord(householdInfo.locationX, householdInfo.locationY) @@ -218,6 +230,20 @@ class UrbanSimScenarioLoader( beamScenario.privateVehicles.put(beamVehicle.id, beamVehicle) vehicleCounter = vehicleCounter + 1 } + if ( beamScenario.beamConfig.beam.agentsim.agents.vehicles.vehicleAdjustmentMethod.equals("STATIC_FROM_FILE")) { + // populate private vehicles here + val vehicles = readers.BeamCsvScenarioReader.readVehiclesFile(beamScenario.beamConfig.beam.agentsim.agents.vehicles.vehiclesFilePath) + .filter(x => Id.create(x.householdId, classOf[Household]).equals(id)); + for { + vehicleInfo <- vehicles + vehicle = buildBeamVehicle(beamScenario.vehicleTypes, vehicleInfo, rand.nextInt) + } { + beamScenario.privateVehicles.put(vehicle.id, vehicle) + vehicleIds.add(vehicle.id) + vehicleCounter = vehicleCounter + 1 + } + } + household.setVehicleIds(vehicleIds) scenarioHouseholds.put(household.getId, household) scenarioHouseholdAttributes.putAttribute(household.getId.toString, "homecoordx", coord.getX) @@ -229,6 +255,34 @@ class UrbanSimScenarioLoader( ) } + + def buildBeamVehicle( + map: Map[Id[BeamVehicleType], BeamVehicleType], + info: VehicleInfo, + randomSeed: Int + ): BeamVehicle = { + val matsimVehicleType: VehicleType = + VehicleUtils.getFactory.createVehicleType(Id.create(info.vehicleTypeId, classOf[VehicleType])) + val matsimVehicle: Vehicle = + VehicleUtils.getFactory.createVehicle(Id.createVehicleId(info.vehicleId), matsimVehicleType) + + val beamVehicleId = Id.create(matsimVehicle.getId, classOf[BeamVehicle]) + val beamVehicleTypeId = Id.create(info.vehicleTypeId, classOf[BeamVehicleType]) + + val beamVehicleType = map(beamVehicleTypeId) + + val vehicleManagerId = + VehicleManager.createOrGetReservedFor(info.householdId, VehicleManager.TypeEnum.Household).managerId + val powerTrain = new Powertrain(beamVehicleType.primaryFuelConsumptionInJoulePerMeter) + new BeamVehicle( + beamVehicleId, + powerTrain, + beamVehicleType, + new AtomicReference(vehicleManagerId), + randomSeed = randomSeed + ) + } + private def getPersonScore(personTravelStats: PersonTravelStats): Double = { val distanceExcludingLastTrip = personTravelStats.tripStats.dropRight(1).map(x => geo.distUTMInMeters(x.origin, x.destination)).sum diff --git a/test/input/beamville/beam-urbansimv2-static.conf b/test/input/beamville/beam-urbansimv2-static.conf new file mode 100755 index 00000000000..51657d72f5b --- /dev/null +++ b/test/input/beamville/beam-urbansimv2-static.conf @@ -0,0 +1,375 @@ +include "../common/akka.conf" +include "../common/metrics.conf" +include "../common/matsim.conf" + +beam.agentsim.simulationName = "beamville-urbansimv2_input" +beam.agentsim.agentSampleSizeAsFractionOfPopulation = 1.0 +beam.agentsim.firstIteration = 0 +beam.agentsim.lastIteration = 0 + +beam.agentsim.thresholdForWalkingInMeters = 100 +beam.agentsim.thresholdForMakingParkingChoiceInMeters = 100 +beam.agentsim.schedulerParallelismWindow = 30 +beam.agentsim.timeBinSize = 3600 +beam.agentsim.startTime = "00:00:00" +beam.agentsim.endTime = "30:00:00" + +# MODE CHOICE OPTIONS: +# ModeChoiceMultinomialLogit ModeChoiceTransitIfAvailable ModeChoiceDriveIfAvailable ModeChoiceRideHailIfAvailable +# ModeChoiceUniformRandom ModeChoiceLCCM +beam.agentsim.agents.modalBehaviors.modeChoiceClass = "ModeChoiceMultinomialLogit" +beam.agentsim.agents.modalBehaviors.defaultValueOfTime = 8.0 +beam.agentsim.agents.modalBehaviors.multinomialLogit.params.transfer = -1.4 +beam.agentsim.agents.modalBehaviors.multinomialLogit.params.car_intercept = 2.0 +beam.agentsim.agents.modalBehaviors.multinomialLogit.params.walk_transit_intercept = 0.0 +beam.agentsim.agents.modalBehaviors.multinomialLogit.params.drive_transit_intercept = 2.0 +beam.agentsim.agents.modalBehaviors.multinomialLogit.params.ride_hail_transit_intercept = 0.0 +beam.agentsim.agents.modalBehaviors.multinomialLogit.params.ride_hail_intercept = 10.0 +beam.agentsim.agents.modalBehaviors.multinomialLogit.params.ride_hail_pooled_intercept = 10.0 +beam.agentsim.agents.modalBehaviors.multinomialLogit.params.walk_intercept = 0.0 +beam.agentsim.agents.modalBehaviors.multinomialLogit.params.bike_intercept = 2.0 +beam.agentsim.agents.modalBehaviors.overrideAutomationLevel = 5 +beam.agentsim.agents.modalBehaviors.overrideAutomationForVOTT = false +beam.agentsim.agents.modalBehaviors.lccm.filePath = ${beam.inputDirectory}"/lccm-long.csv" + +# secondary mode choice +beam.agentsim.agents.tripBehaviors.multinomialLogit.generate_secondary_activities = false +beam.agentsim.agents.tripBehaviors.multinomialLogit.intercept_file_path = ${beam.inputDirectory}"/activity-intercepts.csv" +beam.agentsim.agents.tripBehaviors.multinomialLogit.activity_file_path = ${beam.inputDirectory}"/activity-params.csv" +beam.agentsim.agents.tripBehaviors.multinomialLogit.additional_trip_utility = 0.0 +beam.agentsim.agents.tripBehaviors.multinomialLogit.max_destination_distance_meters = 16000 +beam.agentsim.agents.tripBehaviors.multinomialLogit.max_destination_choice_set_size = 6 +beam.agentsim.agents.tripBehaviors.multinomialLogit.destination_nest_scale_factor = 1.0 +beam.agentsim.agents.tripBehaviors.multinomialLogit.mode_nest_scale_factor = 1.0 +beam.agentsim.agents.tripBehaviors.multinomialLogit.trip_nest_scale_factor = 1.0 + +# beam.agentsim.agents.modeIncentive.filePath = ${beam.inputDirectory}"/incentives.csv" +# beam.agentsim.agents.ptFare.filePath = ${beam.inputDirectory}"/ptFares.csv" +# #BeamVehicles Params +beam.agentsim.agents.vehicles.linkToGradePercentFilePath = ${beam.inputDirectory}"/linkToGradePercent.csv" +beam.agentsim.agents.vehicles.fuelTypesFilePath = ${beam.inputDirectory}"/beamFuelTypes.csv" +beam.agentsim.agents.vehicles.vehicleTypesFilePath = ${beam.inputDirectory}"/vehicleTypes-withoutCAV.csv" +beam.agentsim.agents.vehicles.vehiclesFilePath = ${beam.inputDirectory}"/vehicles-test.csv" +beam.agentsim.agents.vehicles.vehicleAdjustmentMethod = "STATIC_FROM_FILE" +beam.agentsim.agents.vehicles.sharedFleets = [] + +beam.agentsim.agents.vehicles.fractionOfInitialVehicleFleet = 5.0 + +beam.exchange.scenario { + source = "urbansim_v2" + fileFormat = "csv" + folder = ${beam.inputDirectory}"/urbansim_v2" + convertWgs2Utm = true + modeMap = [ + "HOV2 -> hov2" + "HOV3 -> hov3" + "DRIVEALONEPAY -> car" + "DRIVEALONEFREE -> car" + "WALK -> walk" + "BIKE -> bike" + "SHARED3FREE -> car" + "SHARED3PAY -> car" + "SHARED2FREE -> car" + "SHARED2PAY -> car" + "WALK_LOC -> bus" + "DRIVE_LOC -> car" + ] +} + + +# Population Adjustment (DEFAULT_ADJUSTMENT | PERCENTAGE_ADJUSTMENT) +beam.agentsim.populationAdjustment="DEFAULT_ADJUSTMENT" +#Toll params +beam.agentsim.toll.filePath=${beam.inputDirectory}"/toll-prices.csv" +#TAZ params +beam.agentsim.taz.filePath=${beam.inputDirectory}"/taz-centers.csv" +beam.agentsim.taz.parkingFilePath = ${beam.inputDirectory}"/parking/taz-parking-default.csv" +# Scaling and Tuning Params +beam.agentsim.tuning.transitCapacity = 0.1 +beam.agentsim.tuning.transitPrice = 1.0 +beam.agentsim.tuning.tollPrice = 1.0 +beam.agentsim.tuning.rideHailPrice = 1.0 +########################### +# Physsim +########################### +beam.physsim.inputNetworkFilePath = ${beam.routing.r5.directory}"/physsim-network.xml" +beam.physsim.flowCapacityFactor = 0.0001 +beam.physsim.storageCapacityFactor = 1.0 +beam.physsim.writeMATSimNetwork = false +beam.physsim.ptSampleSize = 1.0 +beam.physsim.jdeqsim.agentSimPhysSimInterfaceDebugger.enabled = false +beam.physsim.skipPhysSim = false +beam.physsim.jdeqsim.cacc.enabled = false +beam.physsim.jdeqsim.cacc.minRoadCapacity = 1999 +beam.physsim.jdeqsim.cacc.minSpeedMetersPerSec = 7 +beam.physsim.jdeqsim.cacc.speedAdjustmentFactor = 1.0 + +beam.router.skim = { + h3Resolution = 6 + keepKLatestSkims = 1 + writeSkimsInterval = 1 + writeAggregatedSkimsInterval = 1 + collectFullCarSkimsInterval = 1 + travel-time-skimmer { + name = "travel-time-skimmer" + fileBaseName = "skimsTravelTimeObservedVsSimulated" + } + origin_destination_skimmer { + name = "od-skimmer" + fileBaseName = "skimsOD" + writeAllModeSkimsForPeakNonPeakPeriodsInterval = 0 + writeFullSkimsInterval = 0 + } + taz-skimmer { + name = "taz-skimmer" + fileBaseName = "skimsTAZ" + } +} +#helics +beam.cosim.helics = { + timeStep = "300" + federateName = "BeamFederate" +} +########################### +# Replanning +########################### +beam.replanning { + maxAgentPlanMemorySize = 4 + Module_1 = "SelectExpBeta" + ModuleProbability_1 = 0.7 + Module_2 = "ClearRoutes" + ModuleProbability_2 = 0.2 + Module_3 = "ClearModes" + ModuleProbability_3 = 0.0 + Module_4 = "TimeMutator" + ModuleProbability_4 = 0.1 + fractionOfIterationsToDisableInnovation = 9999999 + cleanNonCarModesInIteration = 1 +} +################################################################## +# Warm Mode +################################################################## + +# Warmstart file path can be given in following format as well. s3://beam-outputs/run140-base__2018-06-26_22-20-49_28e81b6d.zip +beam.warmStart.type = "disabled" + +################################################################## +# RideHail +################################################################## +# Initialization Type(PROCEDURAL | FILE) +beam.agentsim.agents.rideHail.initialization.initType = "PROCEDURAL" +# If PROCEDURAL, use these params +# initialization.procedural.initialLocation.name(INITIAL_RIDE_HAIL_LOCATION_HOME | INITIAL_RIDE_HAIL_LOCATION_UNIFORM_RANDOM | INITIAL_RIDE_HAIL_LOCATION_ALL_AT_CENTER | INITIAL_RIDE_HAIL_LOCATION_ALL_IN_CORNER) +beam.agentsim.agents.rideHail.initialization.procedural.initialLocation.name = "HOME" +beam.agentsim.agents.rideHail.initialization.procedural.initialLocation.home.radiusInMeters = 500 +beam.agentsim.agents.rideHail.initialization.procedural.fractionOfInitialVehicleFleet = 0.5 +beam.agentsim.agents.rideHail.initialization.procedural.vehicleTypeId="beamVilleCar" +# If FILE, use this param +beam.agentsim.agents.rideHail.initialization.filePath=${beam.inputDirectory}"/rideHailFleet.csv" +# Ride Hail Transit Modes: Options are ALL, MASS, or the individual modes comma separate, e.g. BUS,TRAM +beam.agentsim.agents.rideHailTransit.modesToConsider="MASS" +beam.agentsim.agents.rideHail.defaultCostPerMile=1.25 +beam.agentsim.agents.rideHail.defaultCostPerMinute=0.75 +beam.agentsim.agents.rideHail.refuelThresholdInMeters=5000.0 +beam.agentsim.agents.rideHail.rideHailManager.radiusInMeters=5000 +beam.agentsim.agents.rideHail.iterationStats.timeBinSizeInSec=3600 +# SurgePricing parameters +beam.agentsim.agents.rideHail.surgePricing.surgeLevelAdaptionStep=0.1 +beam.agentsim.agents.rideHail.surgePricing.minimumSurgeLevel=0.1 +# priceAdjustmentStrategy(KEEP_PRICE_LEVEL_FIXED_AT_ONE | CONTINUES_DEMAND_SUPPLY_MATCHING) +beam.agentsim.agents.rideHail.surgePricing.priceAdjustmentStrategy="KEEP_PRICE_LEVEL_FIXED_AT_ONE" +# allocationManager(DEFAULT_MANAGER | EV_MANAGER | POOLING_ALONSO_MORA) +beam.agentsim.agents.rideHail.allocationManager.name="POOLING_ALONSO_MORA" +beam.agentsim.agents.rideHail.allocationManager.requestBufferTimeoutInSeconds = 200 +beam.agentsim.agents.rideHail.allocationManager.maxWaitingTimeInSec = 900 +beam.agentsim.agents.rideHail.allocationManager.maxExcessRideTime = 0.5 # up to +50% +# ASYNC_GREEDY_VEHICLE_CENTRIC_MATCHING, ALONSO_MORA_MATCHING_WITH_ASYNC_GREEDY_ASSIGNMENT, ALONSO_MORA_MATCHING_WITH_MIP_ASSIGNMENT +beam.agentsim.agents.rideHail.allocationManager.matchingAlgorithm="ALONSO_MORA_MATCHING_WITH_ASYNC_GREEDY_ASSIGNMENT" +beam.agentsim.agents.rideHail.allocationManager.alonsoMora.maxRequestsPerVehicle = 5 +# repositioningManager can be DEFAULT_REPOSITIONING_MANAGER | DEMAND_FOLLOWING_REPOSITIONING_MANAGER | REPOSITIONING_LOW_WAITING_TIMES | INVERSE_SQUARE_DISTANCE_REPOSITIONING_FACTOR +beam.agentsim.agents.rideHail.repositioningManager.name="DEMAND_FOLLOWING_REPOSITIONING_MANAGER" +beam.agentsim.agents.rideHail.repositioningManager.timeout=300 +# DEMAND_FOLLOWING_REPOSITIONING_MANAGER +beam.agentsim.agents.rideHail.repositioningManager.demandFollowingRepositioningManager.sensitivityOfRepositioningToDemand=1 +beam.agentsim.agents.rideHail.repositioningManager.demandFollowingRepositioningManager.numberOfClustersForDemand=30 +# REPOSITIONING_LOW_WAITING_TIMES +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.percentageOfVehiclesToReposition=1.0 +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.repositionCircleRadiusInMeters = 3000 +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.timeWindowSizeInSecForDecidingAboutRepositioning=1200 +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.allowIncreasingRadiusIfDemandInRadiusLow=true +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.minDemandPercentageInRadius=0.1 +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.minimumNumberOfIdlingVehiclesThresholdForRepositioning = 1 +# repositioningMethod(TOP_SCORES | KMEANS) +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.repositioningMethod="TOP_SCORES" +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.keepMaxTopNScores=5 +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.minScoreThresholdForRepositioning=0.00001 +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.distanceWeight=0.01 +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.waitingTimeWeight=4.0 +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.demandWeight=4.0 +beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.produceDebugImages=true +beam.physsim.quick_fix_minCarSpeedInMetersPerSecond = 0.0 +################################################################## +# OUTPUTS +################################################################## +# The outputDirectory is the base directory where outputs will be written. The beam.agentsim.simulationName param will +# be used as the name of a sub-directory beneath the baseOutputDirectory for simulation results. +# If addTimestampToOutputDirectory == true, a timestamp will be added, e.g. "beamville_2017-12-18_16-48-57" +beam.outputs.baseOutputDirectory = "output/beamville" +beam.outputs.baseOutputDirectory = ${?BEAM_OUTPUT} +beam.outputs.addTimestampToOutputDirectory = true + +# To keep all logging params in one place, BEAM overrides MATSim params normally in the controller config module +beam.outputs.defaultWriteInterval = 1 +beam.outputs.writePlansInterval = ${beam.outputs.defaultWriteInterval} +beam.outputs.writeEventsInterval = ${beam.outputs.defaultWriteInterval} +beam.physsim.writeEventsInterval = ${beam.outputs.defaultWriteInterval} +beam.physsim.writePlansInterval = ${beam.outputs.defaultWriteInterval} +beam.outputs.writeAnalysis = false +beam.outputs.writeLinkTraversalInterval = 0 +beam.physsim.linkStatsWriteInterval = 0 + +# The remaining params customize how events are written to output files +beam.outputs.events.fileOutputFormats = "csv,xml" # valid options: xml(.gz) , csv(.gz), none - DEFAULT: csv.gz + +# Events Writing Logging Levels: +beam.outputs.events.eventsToWrite = "PersonDepartureEvent,PersonArrivalEvent,ActivityEndEvent,ActivityStartEvent,PersonEntersVehicleEvent,PersonLeavesVehicleEvent,ModeChoiceEvent,PathTraversalEvent,ReserveRideHailEvent,ReplanningEvent,RefuelSessionEvent,ChargingPlugInEvent,ChargingPlugOutEvent,ParkingEvent,LeavingParkingEvent,TeleportationEvent" +beam.outputs.stats.binSize = 3600 +################################################################## +# Debugging +################################################################## +beam.debug.debugEnabled = true +beam.debug.debugActorTimerIntervalInSec = 10 +beam.debug.actor.logDepth = 12 + +beam.debug.stuckAgentDetection { + checkIntervalMs = 200 + checkMaxNumberOfMessagesEnabled = true + defaultTimeoutMs = 60000 + enabled = true + overallSimulationTimeoutMs = 100000 + thresholds = [ + { + actorTypeToMaxNumberOfMessages { + population = 1 + rideHailAgent = 1 + transitDriverAgent = 1 + } + markAsStuckAfterMs = 20000 + triggerType = "beam.agentsim.agents.InitializeTrigger" + }, + { + actorTypeToMaxNumberOfMessages { + population = 11 + } + markAsStuckAfterMs = 20000 + triggerType = "beam.agentsim.agents.PersonAgent$ActivityEndTrigger" + }, + { + actorTypeToMaxNumberOfMessages { + population = 1 + } + markAsStuckAfterMs = 20000 + triggerType = "beam.agentsim.agents.PersonAgent$ActivityStartTrigger" + }, + { + actorTypeToMaxNumberOfMessages { + population = 60 + } + markAsStuckAfterMs = 20000 + triggerType = "beam.agentsim.agents.PersonAgent$PersonDepartureTrigger" + }, + { + actorTypeToMaxNumberOfMessages { + population = 20 + } + markAsStuckAfterMs = 20000 + triggerType = "beam.agentsim.agents.modalbehaviors.DrivesVehicle$AlightVehicleTrigger" + }, + { + actorTypeToMaxNumberOfMessages { + population = 20 + } + markAsStuckAfterMs = 20000 + triggerType = "beam.agentsim.agents.modalbehaviors.DrivesVehicle$BoardVehicleTrigger" + }, + { + actorTypeToMaxNumberOfMessages { + population = 80 + rideHailAgent = 400 + transitDriverAgent = 114 + } + markAsStuckAfterMs = 20000 + triggerType = "beam.agentsim.agents.modalbehaviors.DrivesVehicle$EndLegTrigger" + }, + { + actorTypeToMaxNumberOfMessages { + population = 80 + rideHailAgent = 400 + transitDriverAgent = 114 + } + markAsStuckAfterMs = 20000 + triggerType = "beam.agentsim.agents.modalbehaviors.DrivesVehicle$StartLegTrigger" + }, + { + actorTypeToMaxNumberOfMessages { + transitDriverAgent = 1 + } + markAsStuckAfterMs = 20000 + triggerType = "beam.agentsim.scheduler.BeamAgentScheduler$KillTrigger" + + } + ] +} +################################################################## +# SPATIAL +################################################################## +beam.spatial = { + localCRS = "epsg:32631" # what crs to use for distance calculations, must be in units of meters + boundingBoxBuffer = 10000 # meters of buffer around network for defining extend of spatial indices +} + +################################################################## +# BEAM ROUTING SERVICE +################################################################## +beam.routing { + #Base local date in ISO 8061 YYYY-MM-DDTHH:MM:SS+HH:MM + baseDate = "2016-10-17T00:00:00-07:00" + transitOnStreetNetwork = true # PathTraversalEvents for transit vehicles + r5 { + directory = ${beam.inputDirectory}"/r5" + # Departure window in min + departureWindow = 1.0167 + osmFile = ${beam.inputDirectory}"/r5/beamville.osm.pbf" + osmMapdbFile = ${beam.inputDirectory}"/r5/osm.mapdb" + mNetBuilder.fromCRS = "epsg:4326" # WGS84 + mNetBuilder.toCRS = ${beam.spatial.localCRS} + } + startingIterationForTravelTimesMSA = 1 +} + +################################################################## +# Calibration +################################################################## +beam.calibration.objectiveFunction = "ModeChoiceObjectiveFunction" +beam.calibration.mode.benchmarkFilePath=${beam.inputDirectory}"/calibration/benchmark.csv" +beam.calibration.counts { + countsScaleFactor = 10.355 + writeCountsInterval = 0 + averageCountsOverIterations = ${beam.outputs.defaultWriteInterval} +} + +beam.outputs.defaultWriteInterval = 1 +beam.outputs.writePlansInterval = ${beam.outputs.defaultWriteInterval} +beam.outputs.writeEventsInterval = ${beam.outputs.defaultWriteInterval} +beam.physsim.writeEventsInterval = ${beam.outputs.defaultWriteInterval} +beam.physsim.writePlansInterval = ${beam.outputs.defaultWriteInterval} + +beam.agentsim.agents.population.useVehicleSampling = "true" + +beam.agentsim.agents.rideHail.initialization.procedural.fractionOfInitialVehicleFleet = 0.1 + +beam.debug.messageLogging = true + +beam.agentsim.agents.vehicles.dummySharedCar.vehicleTypeId = "sharedVehicle-sharedCar" + + diff --git a/test/input/beamville/vehicles-test.csv b/test/input/beamville/vehicles-test.csv new file mode 100644 index 00000000000..2d45b90f407 --- /dev/null +++ b/test/input/beamville/vehicles-test.csv @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00dd15ef586972d118620a8cd9524eb51827d17b848539fb0a5c031ba022f763 +size 690 From e93a268ca20d884b365ae2a66c220183a7f4e25a Mon Sep 17 00:00:00 2001 From: Alvin Lee Jin Wen Date: Mon, 29 Aug 2022 23:30:17 +0800 Subject: [PATCH 2/5] move logic into vehiclesAdjustment, keep other files clean --- .../agents/household/HouseholdActor.scala | 3 +- .../vehicles/DefaultVehiclesAdjustment.scala | 4 +- .../vehicles/FromFileVehiclesAdjustment.scala | 55 ++++++++++++++++++ .../IncomeBasedVehiclesAdjustment.scala | 6 +- .../sim/vehicles/NoOpVehiclesAdjustment.scala | 30 ---------- .../vehicles/UniformVehiclesAdjustment.scala | 6 +- .../sim/vehicles/VehiclesAdjustment.scala | 8 ++- .../scenario/UrbanSimScenarioLoader.scala | 58 ++----------------- 8 files changed, 77 insertions(+), 93 deletions(-) create mode 100644 src/main/scala/beam/sim/vehicles/FromFileVehiclesAdjustment.scala delete mode 100644 src/main/scala/beam/sim/vehicles/NoOpVehiclesAdjustment.scala diff --git a/src/main/scala/beam/agentsim/agents/household/HouseholdActor.scala b/src/main/scala/beam/agentsim/agents/household/HouseholdActor.scala index a8ad0686018..f8787a918d1 100755 --- a/src/main/scala/beam/agentsim/agents/household/HouseholdActor.scala +++ b/src/main/scala/beam/agentsim/agents/household/HouseholdActor.scala @@ -632,7 +632,8 @@ object HouseholdActor { household.getMemberIds.size(), householdPopulation = null, whenWhere.loc, - realDistribution + realDistribution, + household.getId ) .headOption .orElse { diff --git a/src/main/scala/beam/sim/vehicles/DefaultVehiclesAdjustment.scala b/src/main/scala/beam/sim/vehicles/DefaultVehiclesAdjustment.scala index 3450eaae7b5..b22fe7ebb27 100644 --- a/src/main/scala/beam/sim/vehicles/DefaultVehiclesAdjustment.scala +++ b/src/main/scala/beam/sim/vehicles/DefaultVehiclesAdjustment.scala @@ -6,6 +6,7 @@ import beam.agentsim.agents.vehicles.VehicleCategory.VehicleCategory import beam.sim.{BeamScenario, BeamServices} import org.apache.commons.math3.distribution.UniformRealDistribution import org.matsim.api.core.v01.{Coord, Id} +import org.matsim.households.Household case class DefaultVehiclesAdjustment(beamServices: BeamServices, beamScenario: BeamScenario) extends VehiclesAdjustment { @@ -28,7 +29,8 @@ case class DefaultVehiclesAdjustment(beamServices: BeamServices, beamScenario: B householdSize: Int, householdPopulation: Population, householdLocation: Coord, - realDistribution: UniformRealDistribution + realDistribution: UniformRealDistribution, + householdId: Id[Household] ): List[BeamVehicleType] = { if (vehicleCategory != VehicleCategory.Car) throw new NotImplementedError(vehicleCategory.toString) List.fill(numVehicles)(vehicleTypesByCategory) diff --git a/src/main/scala/beam/sim/vehicles/FromFileVehiclesAdjustment.scala b/src/main/scala/beam/sim/vehicles/FromFileVehiclesAdjustment.scala new file mode 100644 index 00000000000..515d462e449 --- /dev/null +++ b/src/main/scala/beam/sim/vehicles/FromFileVehiclesAdjustment.scala @@ -0,0 +1,55 @@ +package beam.sim.vehicles + +import beam.agentsim.agents.Population +import beam.agentsim.agents.vehicles.{BeamVehicleType, VehicleCategory} +import beam.sim.{BeamScenario, BeamServices} +import beam.utils.csv.readers +import beam.utils.scenario.VehicleInfo +import org.apache.commons.math3.distribution.UniformRealDistribution +import org.matsim.api.core.v01.{Coord, Id} +import org.matsim.households.Household + +case class FromFileVehiclesAdjustment(beamScenario: BeamScenario) extends VehiclesAdjustment { + + var vehicles: Iterable[VehicleInfo] = List(); + var vehicleTypesMap: Map[Id[BeamVehicleType], BeamVehicleType] = Map(); + + override def sampleVehicleTypesForHousehold( + numVehicles: Int, + vehicleCategory: VehicleCategory.VehicleCategory, + householdIncome: Double, + householdSize: Int, + householdPopulation: Population, + householdLocation: Coord, + realDistribution: UniformRealDistribution, + householdId: Id[Household] = Id.create("", classOf[Household]) + ): List[BeamVehicleType] = { + vehicles + .filter(x => Id.create(x.householdId, classOf[Household]).equals(householdId)) + .map(x => Id.create(x.vehicleTypeId, classOf[BeamVehicleType])) + .map(x => vehicleTypesMap(x)) + .toList + } + + override def sampleVehicleTypes( + numVehicles: Int, + vehicleCategory: VehicleCategory.VehicleCategory, + realDistribution: UniformRealDistribution + ): List[BeamVehicleType] = { + List() + } + + def readVechiclesFromFile() = { + readers.BeamCsvScenarioReader.readVehiclesFile( + beamScenario.beamConfig.beam.agentsim.agents.vehicles.vehiclesFilePath + ) + } +} + +object FromFileVehiclesAdjustment { + + def apply(beamScenario: BeamScenario) = new FromFileVehiclesAdjustment(beamScenario) { + vehicles = readVechiclesFromFile() + vehicleTypesMap = beamScenario.vehicleTypes.map(i => i._1 -> i._2).toMap + } +} diff --git a/src/main/scala/beam/sim/vehicles/IncomeBasedVehiclesAdjustment.scala b/src/main/scala/beam/sim/vehicles/IncomeBasedVehiclesAdjustment.scala index 800a5f108cb..8868f930fef 100644 --- a/src/main/scala/beam/sim/vehicles/IncomeBasedVehiclesAdjustment.scala +++ b/src/main/scala/beam/sim/vehicles/IncomeBasedVehiclesAdjustment.scala @@ -5,7 +5,8 @@ import beam.agentsim.agents.vehicles.BeamVehicleType import beam.agentsim.agents.vehicles.VehicleCategory.VehicleCategory import beam.sim.BeamScenario import org.apache.commons.math3.distribution.UniformRealDistribution -import org.matsim.api.core.v01.Coord +import org.matsim.api.core.v01.{Coord, Id} +import org.matsim.households.Household case class IncomeBasedVehiclesAdjustment(beamScenario: BeamScenario) extends VehiclesAdjustment { @@ -25,7 +26,8 @@ case class IncomeBasedVehiclesAdjustment(beamScenario: BeamScenario) extends Veh householdSize: Int, householdPopulation: Population, householdLocation: Coord, - realDistribution: UniformRealDistribution + realDistribution: UniformRealDistribution, + householdId: Id[Household] ): List[BeamVehicleType] = { val matchedGroups = vehicleTypesAndProbabilityByCategoryAndGroup.keys.filter(x => isThisHouseholdInThisGroup(householdIncome, x)) diff --git a/src/main/scala/beam/sim/vehicles/NoOpVehiclesAdjustment.scala b/src/main/scala/beam/sim/vehicles/NoOpVehiclesAdjustment.scala deleted file mode 100644 index adfed18b852..00000000000 --- a/src/main/scala/beam/sim/vehicles/NoOpVehiclesAdjustment.scala +++ /dev/null @@ -1,30 +0,0 @@ -package beam.sim.vehicles - -import beam.agentsim.agents.Population -import beam.agentsim.agents.vehicles.VehicleCategory.VehicleCategory -import beam.agentsim.agents.vehicles.{BeamVehicleType, VehicleCategory} -import beam.sim.BeamScenario -import org.apache.commons.math3.distribution.UniformRealDistribution -import org.matsim.api.core.v01.Coord - -case class NoOpVehiclesAdjustment(beamScenario: BeamScenario) extends VehiclesAdjustment { - override def sampleVehicleTypesForHousehold( - numVehicles: Int, - vehicleCategory: VehicleCategory, - householdIncome: Double, - householdSize: Int, - householdPopulation: Population, - householdLocation: Coord, - realDistribution: UniformRealDistribution - ): List[BeamVehicleType] = { - List() - } - - override def sampleVehicleTypes( - numVehicles: Int, - vehicleCategory: VehicleCategory, - realDistribution: UniformRealDistribution - ): List[BeamVehicleType] = { - List() - } -} diff --git a/src/main/scala/beam/sim/vehicles/UniformVehiclesAdjustment.scala b/src/main/scala/beam/sim/vehicles/UniformVehiclesAdjustment.scala index 3cd534663dd..62489f3be3e 100644 --- a/src/main/scala/beam/sim/vehicles/UniformVehiclesAdjustment.scala +++ b/src/main/scala/beam/sim/vehicles/UniformVehiclesAdjustment.scala @@ -5,7 +5,8 @@ import beam.agentsim.agents.vehicles.BeamVehicleType import beam.agentsim.agents.vehicles.VehicleCategory.VehicleCategory import beam.sim.{BeamScenario, BeamServices} import org.apache.commons.math3.distribution.UniformRealDistribution -import org.matsim.api.core.v01.Coord +import org.matsim.api.core.v01.{Coord, Id} +import org.matsim.households.Household case class UniformVehiclesAdjustment(beamScenario: BeamScenario) extends VehiclesAdjustment { @@ -30,7 +31,8 @@ case class UniformVehiclesAdjustment(beamScenario: BeamScenario) extends Vehicle householdSize: Int, householdPopulation: Population, householdLocation: Coord, - realDistribution: UniformRealDistribution + realDistribution: UniformRealDistribution, + householdId: Id[Household] ): List[BeamVehicleType] = { val vehTypeWithProbability = vehicleTypesAndProbabilitiesByCategory(vehicleCategory, "Usage Not Set") (1 to numVehicles).map { _ => diff --git a/src/main/scala/beam/sim/vehicles/VehiclesAdjustment.scala b/src/main/scala/beam/sim/vehicles/VehiclesAdjustment.scala index 5bbc3f83b6e..833aa619b3b 100644 --- a/src/main/scala/beam/sim/vehicles/VehiclesAdjustment.scala +++ b/src/main/scala/beam/sim/vehicles/VehiclesAdjustment.scala @@ -6,7 +6,8 @@ import beam.agentsim.agents.vehicles.VehicleCategory.VehicleCategory import beam.sim.BeamScenario import beam.utils.logging.ExponentialLazyLogging import org.apache.commons.math3.distribution.UniformRealDistribution -import org.matsim.api.core.v01.Coord +import org.matsim.api.core.v01.{Coord, Id} +import org.matsim.households.Household trait VehiclesAdjustment extends ExponentialLazyLogging { @@ -17,7 +18,8 @@ trait VehiclesAdjustment extends ExponentialLazyLogging { householdSize: Int, householdPopulation: Population, householdLocation: Coord, - realDistribution: UniformRealDistribution + realDistribution: UniformRealDistribution, + householdId: Id[Household] ): List[BeamVehicleType] def sampleVehicleTypes( @@ -36,7 +38,7 @@ object VehiclesAdjustment { def getVehicleAdjustment(beamScenario: BeamScenario): VehiclesAdjustment = { beamScenario.beamConfig.beam.agentsim.agents.vehicles.vehicleAdjustmentMethod match { case UNIFORM_ADJUSTMENT => UniformVehiclesAdjustment(beamScenario) - case STATIC_FROM_FILE => NoOpVehiclesAdjustment(beamScenario) + case STATIC_FROM_FILE => FromFileVehiclesAdjustment(beamScenario) case INCOME_BASED_ADJUSTMENT => IncomeBasedVehiclesAdjustment(beamScenario) case _ => UniformVehiclesAdjustment(beamScenario) } diff --git a/src/main/scala/beam/utils/scenario/UrbanSimScenarioLoader.scala b/src/main/scala/beam/utils/scenario/UrbanSimScenarioLoader.scala index 5177c878b42..c3df4cddd40 100644 --- a/src/main/scala/beam/utils/scenario/UrbanSimScenarioLoader.scala +++ b/src/main/scala/beam/utils/scenario/UrbanSimScenarioLoader.scala @@ -24,7 +24,7 @@ import org.matsim.vehicles.{Vehicle, VehicleType, VehicleUtils} import java.util.concurrent.atomic.AtomicReference import scala.collection.JavaConverters._ import scala.collection.mutable.ArrayBuffer -import scala.collection.{Iterable, mutable} +import scala.collection.{mutable, Iterable} import scala.concurrent.duration._ import scala.concurrent.{Await, ExecutionContext, Future} import scala.math.{max, min, round} @@ -61,14 +61,6 @@ class UrbanSimScenarioLoader( def loadScenario(): (Scenario, Boolean) = { clear() -// for { -// vehicleInfo <- vehicles -// vehicle = buildBeamVehicle(beamScenario.vehicleTypes, vehicleInfo, rand.nextInt) -// } { -// beamScenario.privateVehicles.put(vehicle.id, vehicle) -// vehicleInfo.initialSoc.foreach(beamScenario.privateVehicleInitialSoc.put(vehicle.id, _)) -// } - val plansF = Future { val plans = scenarioSource.getPlans logger.info(s"Read ${plans.size} plans") @@ -179,8 +171,7 @@ class UrbanSimScenarioLoader( .find(_.vehicleCategory == VehicleCategory.Bike) .getOrElse(throw new RuntimeException("Bike not found in vehicle types.")) - assignVehicles(households, householdIdToPersons, personId2Score).foreach { - case (householdInfo, nVehicles) => + assignVehicles(households, householdIdToPersons, personId2Score).foreach { case (householdInfo, nVehicles) => val id = Id.create(householdInfo.householdId.id, classOf[Household]) val household = new HouseholdsFactoryImpl().createHousehold(id) val coord = utmCoord(householdInfo.locationX, householdInfo.locationY) @@ -203,7 +194,8 @@ class UrbanSimScenarioLoader( householdSize = household.getMemberIds.size, householdPopulation = null, householdLocation = coord, - realDistribution + realDistribution, + householdId = household.getId ) .toBuffer @@ -230,20 +222,6 @@ class UrbanSimScenarioLoader( beamScenario.privateVehicles.put(beamVehicle.id, beamVehicle) vehicleCounter = vehicleCounter + 1 } - if ( beamScenario.beamConfig.beam.agentsim.agents.vehicles.vehicleAdjustmentMethod.equals("STATIC_FROM_FILE")) { - // populate private vehicles here - val vehicles = readers.BeamCsvScenarioReader.readVehiclesFile(beamScenario.beamConfig.beam.agentsim.agents.vehicles.vehiclesFilePath) - .filter(x => Id.create(x.householdId, classOf[Household]).equals(id)); - for { - vehicleInfo <- vehicles - vehicle = buildBeamVehicle(beamScenario.vehicleTypes, vehicleInfo, rand.nextInt) - } { - beamScenario.privateVehicles.put(vehicle.id, vehicle) - vehicleIds.add(vehicle.id) - vehicleCounter = vehicleCounter + 1 - } - } - household.setVehicleIds(vehicleIds) scenarioHouseholds.put(household.getId, household) scenarioHouseholdAttributes.putAttribute(household.getId.toString, "homecoordx", coord.getX) @@ -255,34 +233,6 @@ class UrbanSimScenarioLoader( ) } - - def buildBeamVehicle( - map: Map[Id[BeamVehicleType], BeamVehicleType], - info: VehicleInfo, - randomSeed: Int - ): BeamVehicle = { - val matsimVehicleType: VehicleType = - VehicleUtils.getFactory.createVehicleType(Id.create(info.vehicleTypeId, classOf[VehicleType])) - val matsimVehicle: Vehicle = - VehicleUtils.getFactory.createVehicle(Id.createVehicleId(info.vehicleId), matsimVehicleType) - - val beamVehicleId = Id.create(matsimVehicle.getId, classOf[BeamVehicle]) - val beamVehicleTypeId = Id.create(info.vehicleTypeId, classOf[BeamVehicleType]) - - val beamVehicleType = map(beamVehicleTypeId) - - val vehicleManagerId = - VehicleManager.createOrGetReservedFor(info.householdId, VehicleManager.TypeEnum.Household).managerId - val powerTrain = new Powertrain(beamVehicleType.primaryFuelConsumptionInJoulePerMeter) - new BeamVehicle( - beamVehicleId, - powerTrain, - beamVehicleType, - new AtomicReference(vehicleManagerId), - randomSeed = randomSeed - ) - } - private def getPersonScore(personTravelStats: PersonTravelStats): Double = { val distanceExcludingLastTrip = personTravelStats.tripStats.dropRight(1).map(x => geo.distUTMInMeters(x.origin, x.destination)).sum From 9d3f605246c73b9a8b49f693924a492f6b89291e Mon Sep 17 00:00:00 2001 From: Alvin Lee Jin Wen Date: Tue, 30 Aug 2022 23:01:14 +0800 Subject: [PATCH 3/5] code cleanup --- .../vehicles/FromFileVehiclesAdjustment.scala | 18 +- .../beamville/beam-urbansimv2-static.conf | 371 +----------------- 2 files changed, 7 insertions(+), 382 deletions(-) diff --git a/src/main/scala/beam/sim/vehicles/FromFileVehiclesAdjustment.scala b/src/main/scala/beam/sim/vehicles/FromFileVehiclesAdjustment.scala index 515d462e449..ac5f39c2325 100644 --- a/src/main/scala/beam/sim/vehicles/FromFileVehiclesAdjustment.scala +++ b/src/main/scala/beam/sim/vehicles/FromFileVehiclesAdjustment.scala @@ -11,8 +11,8 @@ import org.matsim.households.Household case class FromFileVehiclesAdjustment(beamScenario: BeamScenario) extends VehiclesAdjustment { - var vehicles: Iterable[VehicleInfo] = List(); - var vehicleTypesMap: Map[Id[BeamVehicleType], BeamVehicleType] = Map(); + val vehicles: Iterable[VehicleInfo] = readVehiclesFromFile(); + val vehicleTypesMap: Map[Id[BeamVehicleType], BeamVehicleType] = beamScenario.vehicleTypes.map(i => i._1 -> i._2).toMap; override def sampleVehicleTypesForHousehold( numVehicles: Int, @@ -22,7 +22,7 @@ case class FromFileVehiclesAdjustment(beamScenario: BeamScenario) extends Vehicl householdPopulation: Population, householdLocation: Coord, realDistribution: UniformRealDistribution, - householdId: Id[Household] = Id.create("", classOf[Household]) + householdId: Id[Household] ): List[BeamVehicleType] = { vehicles .filter(x => Id.create(x.householdId, classOf[Household]).equals(householdId)) @@ -39,17 +39,9 @@ case class FromFileVehiclesAdjustment(beamScenario: BeamScenario) extends Vehicl List() } - def readVechiclesFromFile() = { + private def readVehiclesFromFile() = { readers.BeamCsvScenarioReader.readVehiclesFile( beamScenario.beamConfig.beam.agentsim.agents.vehicles.vehiclesFilePath ) } -} - -object FromFileVehiclesAdjustment { - - def apply(beamScenario: BeamScenario) = new FromFileVehiclesAdjustment(beamScenario) { - vehicles = readVechiclesFromFile() - vehicleTypesMap = beamScenario.vehicleTypes.map(i => i._1 -> i._2).toMap - } -} +} \ No newline at end of file diff --git a/test/input/beamville/beam-urbansimv2-static.conf b/test/input/beamville/beam-urbansimv2-static.conf index 51657d72f5b..dfcc80b4f07 100755 --- a/test/input/beamville/beam-urbansimv2-static.conf +++ b/test/input/beamville/beam-urbansimv2-static.conf @@ -1,375 +1,8 @@ include "../common/akka.conf" include "../common/metrics.conf" include "../common/matsim.conf" +include "beam-urbansimv2.conf" -beam.agentsim.simulationName = "beamville-urbansimv2_input" -beam.agentsim.agentSampleSizeAsFractionOfPopulation = 1.0 -beam.agentsim.firstIteration = 0 -beam.agentsim.lastIteration = 0 - -beam.agentsim.thresholdForWalkingInMeters = 100 -beam.agentsim.thresholdForMakingParkingChoiceInMeters = 100 -beam.agentsim.schedulerParallelismWindow = 30 -beam.agentsim.timeBinSize = 3600 -beam.agentsim.startTime = "00:00:00" -beam.agentsim.endTime = "30:00:00" - -# MODE CHOICE OPTIONS: -# ModeChoiceMultinomialLogit ModeChoiceTransitIfAvailable ModeChoiceDriveIfAvailable ModeChoiceRideHailIfAvailable -# ModeChoiceUniformRandom ModeChoiceLCCM -beam.agentsim.agents.modalBehaviors.modeChoiceClass = "ModeChoiceMultinomialLogit" -beam.agentsim.agents.modalBehaviors.defaultValueOfTime = 8.0 -beam.agentsim.agents.modalBehaviors.multinomialLogit.params.transfer = -1.4 -beam.agentsim.agents.modalBehaviors.multinomialLogit.params.car_intercept = 2.0 -beam.agentsim.agents.modalBehaviors.multinomialLogit.params.walk_transit_intercept = 0.0 -beam.agentsim.agents.modalBehaviors.multinomialLogit.params.drive_transit_intercept = 2.0 -beam.agentsim.agents.modalBehaviors.multinomialLogit.params.ride_hail_transit_intercept = 0.0 -beam.agentsim.agents.modalBehaviors.multinomialLogit.params.ride_hail_intercept = 10.0 -beam.agentsim.agents.modalBehaviors.multinomialLogit.params.ride_hail_pooled_intercept = 10.0 -beam.agentsim.agents.modalBehaviors.multinomialLogit.params.walk_intercept = 0.0 -beam.agentsim.agents.modalBehaviors.multinomialLogit.params.bike_intercept = 2.0 -beam.agentsim.agents.modalBehaviors.overrideAutomationLevel = 5 -beam.agentsim.agents.modalBehaviors.overrideAutomationForVOTT = false -beam.agentsim.agents.modalBehaviors.lccm.filePath = ${beam.inputDirectory}"/lccm-long.csv" - -# secondary mode choice -beam.agentsim.agents.tripBehaviors.multinomialLogit.generate_secondary_activities = false -beam.agentsim.agents.tripBehaviors.multinomialLogit.intercept_file_path = ${beam.inputDirectory}"/activity-intercepts.csv" -beam.agentsim.agents.tripBehaviors.multinomialLogit.activity_file_path = ${beam.inputDirectory}"/activity-params.csv" -beam.agentsim.agents.tripBehaviors.multinomialLogit.additional_trip_utility = 0.0 -beam.agentsim.agents.tripBehaviors.multinomialLogit.max_destination_distance_meters = 16000 -beam.agentsim.agents.tripBehaviors.multinomialLogit.max_destination_choice_set_size = 6 -beam.agentsim.agents.tripBehaviors.multinomialLogit.destination_nest_scale_factor = 1.0 -beam.agentsim.agents.tripBehaviors.multinomialLogit.mode_nest_scale_factor = 1.0 -beam.agentsim.agents.tripBehaviors.multinomialLogit.trip_nest_scale_factor = 1.0 - -# beam.agentsim.agents.modeIncentive.filePath = ${beam.inputDirectory}"/incentives.csv" -# beam.agentsim.agents.ptFare.filePath = ${beam.inputDirectory}"/ptFares.csv" -# #BeamVehicles Params -beam.agentsim.agents.vehicles.linkToGradePercentFilePath = ${beam.inputDirectory}"/linkToGradePercent.csv" -beam.agentsim.agents.vehicles.fuelTypesFilePath = ${beam.inputDirectory}"/beamFuelTypes.csv" -beam.agentsim.agents.vehicles.vehicleTypesFilePath = ${beam.inputDirectory}"/vehicleTypes-withoutCAV.csv" +beam.agentsim.simulationName = "beamville-urbansimv2_static" beam.agentsim.agents.vehicles.vehiclesFilePath = ${beam.inputDirectory}"/vehicles-test.csv" beam.agentsim.agents.vehicles.vehicleAdjustmentMethod = "STATIC_FROM_FILE" -beam.agentsim.agents.vehicles.sharedFleets = [] - -beam.agentsim.agents.vehicles.fractionOfInitialVehicleFleet = 5.0 - -beam.exchange.scenario { - source = "urbansim_v2" - fileFormat = "csv" - folder = ${beam.inputDirectory}"/urbansim_v2" - convertWgs2Utm = true - modeMap = [ - "HOV2 -> hov2" - "HOV3 -> hov3" - "DRIVEALONEPAY -> car" - "DRIVEALONEFREE -> car" - "WALK -> walk" - "BIKE -> bike" - "SHARED3FREE -> car" - "SHARED3PAY -> car" - "SHARED2FREE -> car" - "SHARED2PAY -> car" - "WALK_LOC -> bus" - "DRIVE_LOC -> car" - ] -} - - -# Population Adjustment (DEFAULT_ADJUSTMENT | PERCENTAGE_ADJUSTMENT) -beam.agentsim.populationAdjustment="DEFAULT_ADJUSTMENT" -#Toll params -beam.agentsim.toll.filePath=${beam.inputDirectory}"/toll-prices.csv" -#TAZ params -beam.agentsim.taz.filePath=${beam.inputDirectory}"/taz-centers.csv" -beam.agentsim.taz.parkingFilePath = ${beam.inputDirectory}"/parking/taz-parking-default.csv" -# Scaling and Tuning Params -beam.agentsim.tuning.transitCapacity = 0.1 -beam.agentsim.tuning.transitPrice = 1.0 -beam.agentsim.tuning.tollPrice = 1.0 -beam.agentsim.tuning.rideHailPrice = 1.0 -########################### -# Physsim -########################### -beam.physsim.inputNetworkFilePath = ${beam.routing.r5.directory}"/physsim-network.xml" -beam.physsim.flowCapacityFactor = 0.0001 -beam.physsim.storageCapacityFactor = 1.0 -beam.physsim.writeMATSimNetwork = false -beam.physsim.ptSampleSize = 1.0 -beam.physsim.jdeqsim.agentSimPhysSimInterfaceDebugger.enabled = false -beam.physsim.skipPhysSim = false -beam.physsim.jdeqsim.cacc.enabled = false -beam.physsim.jdeqsim.cacc.minRoadCapacity = 1999 -beam.physsim.jdeqsim.cacc.minSpeedMetersPerSec = 7 -beam.physsim.jdeqsim.cacc.speedAdjustmentFactor = 1.0 - -beam.router.skim = { - h3Resolution = 6 - keepKLatestSkims = 1 - writeSkimsInterval = 1 - writeAggregatedSkimsInterval = 1 - collectFullCarSkimsInterval = 1 - travel-time-skimmer { - name = "travel-time-skimmer" - fileBaseName = "skimsTravelTimeObservedVsSimulated" - } - origin_destination_skimmer { - name = "od-skimmer" - fileBaseName = "skimsOD" - writeAllModeSkimsForPeakNonPeakPeriodsInterval = 0 - writeFullSkimsInterval = 0 - } - taz-skimmer { - name = "taz-skimmer" - fileBaseName = "skimsTAZ" - } -} -#helics -beam.cosim.helics = { - timeStep = "300" - federateName = "BeamFederate" -} -########################### -# Replanning -########################### -beam.replanning { - maxAgentPlanMemorySize = 4 - Module_1 = "SelectExpBeta" - ModuleProbability_1 = 0.7 - Module_2 = "ClearRoutes" - ModuleProbability_2 = 0.2 - Module_3 = "ClearModes" - ModuleProbability_3 = 0.0 - Module_4 = "TimeMutator" - ModuleProbability_4 = 0.1 - fractionOfIterationsToDisableInnovation = 9999999 - cleanNonCarModesInIteration = 1 -} -################################################################## -# Warm Mode -################################################################## - -# Warmstart file path can be given in following format as well. s3://beam-outputs/run140-base__2018-06-26_22-20-49_28e81b6d.zip -beam.warmStart.type = "disabled" - -################################################################## -# RideHail -################################################################## -# Initialization Type(PROCEDURAL | FILE) -beam.agentsim.agents.rideHail.initialization.initType = "PROCEDURAL" -# If PROCEDURAL, use these params -# initialization.procedural.initialLocation.name(INITIAL_RIDE_HAIL_LOCATION_HOME | INITIAL_RIDE_HAIL_LOCATION_UNIFORM_RANDOM | INITIAL_RIDE_HAIL_LOCATION_ALL_AT_CENTER | INITIAL_RIDE_HAIL_LOCATION_ALL_IN_CORNER) -beam.agentsim.agents.rideHail.initialization.procedural.initialLocation.name = "HOME" -beam.agentsim.agents.rideHail.initialization.procedural.initialLocation.home.radiusInMeters = 500 -beam.agentsim.agents.rideHail.initialization.procedural.fractionOfInitialVehicleFleet = 0.5 -beam.agentsim.agents.rideHail.initialization.procedural.vehicleTypeId="beamVilleCar" -# If FILE, use this param -beam.agentsim.agents.rideHail.initialization.filePath=${beam.inputDirectory}"/rideHailFleet.csv" -# Ride Hail Transit Modes: Options are ALL, MASS, or the individual modes comma separate, e.g. BUS,TRAM -beam.agentsim.agents.rideHailTransit.modesToConsider="MASS" -beam.agentsim.agents.rideHail.defaultCostPerMile=1.25 -beam.agentsim.agents.rideHail.defaultCostPerMinute=0.75 -beam.agentsim.agents.rideHail.refuelThresholdInMeters=5000.0 -beam.agentsim.agents.rideHail.rideHailManager.radiusInMeters=5000 -beam.agentsim.agents.rideHail.iterationStats.timeBinSizeInSec=3600 -# SurgePricing parameters -beam.agentsim.agents.rideHail.surgePricing.surgeLevelAdaptionStep=0.1 -beam.agentsim.agents.rideHail.surgePricing.minimumSurgeLevel=0.1 -# priceAdjustmentStrategy(KEEP_PRICE_LEVEL_FIXED_AT_ONE | CONTINUES_DEMAND_SUPPLY_MATCHING) -beam.agentsim.agents.rideHail.surgePricing.priceAdjustmentStrategy="KEEP_PRICE_LEVEL_FIXED_AT_ONE" -# allocationManager(DEFAULT_MANAGER | EV_MANAGER | POOLING_ALONSO_MORA) -beam.agentsim.agents.rideHail.allocationManager.name="POOLING_ALONSO_MORA" -beam.agentsim.agents.rideHail.allocationManager.requestBufferTimeoutInSeconds = 200 -beam.agentsim.agents.rideHail.allocationManager.maxWaitingTimeInSec = 900 -beam.agentsim.agents.rideHail.allocationManager.maxExcessRideTime = 0.5 # up to +50% -# ASYNC_GREEDY_VEHICLE_CENTRIC_MATCHING, ALONSO_MORA_MATCHING_WITH_ASYNC_GREEDY_ASSIGNMENT, ALONSO_MORA_MATCHING_WITH_MIP_ASSIGNMENT -beam.agentsim.agents.rideHail.allocationManager.matchingAlgorithm="ALONSO_MORA_MATCHING_WITH_ASYNC_GREEDY_ASSIGNMENT" -beam.agentsim.agents.rideHail.allocationManager.alonsoMora.maxRequestsPerVehicle = 5 -# repositioningManager can be DEFAULT_REPOSITIONING_MANAGER | DEMAND_FOLLOWING_REPOSITIONING_MANAGER | REPOSITIONING_LOW_WAITING_TIMES | INVERSE_SQUARE_DISTANCE_REPOSITIONING_FACTOR -beam.agentsim.agents.rideHail.repositioningManager.name="DEMAND_FOLLOWING_REPOSITIONING_MANAGER" -beam.agentsim.agents.rideHail.repositioningManager.timeout=300 -# DEMAND_FOLLOWING_REPOSITIONING_MANAGER -beam.agentsim.agents.rideHail.repositioningManager.demandFollowingRepositioningManager.sensitivityOfRepositioningToDemand=1 -beam.agentsim.agents.rideHail.repositioningManager.demandFollowingRepositioningManager.numberOfClustersForDemand=30 -# REPOSITIONING_LOW_WAITING_TIMES -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.percentageOfVehiclesToReposition=1.0 -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.repositionCircleRadiusInMeters = 3000 -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.timeWindowSizeInSecForDecidingAboutRepositioning=1200 -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.allowIncreasingRadiusIfDemandInRadiusLow=true -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.minDemandPercentageInRadius=0.1 -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.minimumNumberOfIdlingVehiclesThresholdForRepositioning = 1 -# repositioningMethod(TOP_SCORES | KMEANS) -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.repositioningMethod="TOP_SCORES" -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.keepMaxTopNScores=5 -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.minScoreThresholdForRepositioning=0.00001 -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.distanceWeight=0.01 -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.waitingTimeWeight=4.0 -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.demandWeight=4.0 -beam.agentsim.agents.rideHail.allocationManager.repositionLowWaitingTimes.produceDebugImages=true -beam.physsim.quick_fix_minCarSpeedInMetersPerSecond = 0.0 -################################################################## -# OUTPUTS -################################################################## -# The outputDirectory is the base directory where outputs will be written. The beam.agentsim.simulationName param will -# be used as the name of a sub-directory beneath the baseOutputDirectory for simulation results. -# If addTimestampToOutputDirectory == true, a timestamp will be added, e.g. "beamville_2017-12-18_16-48-57" -beam.outputs.baseOutputDirectory = "output/beamville" -beam.outputs.baseOutputDirectory = ${?BEAM_OUTPUT} -beam.outputs.addTimestampToOutputDirectory = true - -# To keep all logging params in one place, BEAM overrides MATSim params normally in the controller config module -beam.outputs.defaultWriteInterval = 1 -beam.outputs.writePlansInterval = ${beam.outputs.defaultWriteInterval} -beam.outputs.writeEventsInterval = ${beam.outputs.defaultWriteInterval} -beam.physsim.writeEventsInterval = ${beam.outputs.defaultWriteInterval} -beam.physsim.writePlansInterval = ${beam.outputs.defaultWriteInterval} -beam.outputs.writeAnalysis = false -beam.outputs.writeLinkTraversalInterval = 0 -beam.physsim.linkStatsWriteInterval = 0 - -# The remaining params customize how events are written to output files -beam.outputs.events.fileOutputFormats = "csv,xml" # valid options: xml(.gz) , csv(.gz), none - DEFAULT: csv.gz - -# Events Writing Logging Levels: -beam.outputs.events.eventsToWrite = "PersonDepartureEvent,PersonArrivalEvent,ActivityEndEvent,ActivityStartEvent,PersonEntersVehicleEvent,PersonLeavesVehicleEvent,ModeChoiceEvent,PathTraversalEvent,ReserveRideHailEvent,ReplanningEvent,RefuelSessionEvent,ChargingPlugInEvent,ChargingPlugOutEvent,ParkingEvent,LeavingParkingEvent,TeleportationEvent" -beam.outputs.stats.binSize = 3600 -################################################################## -# Debugging -################################################################## -beam.debug.debugEnabled = true -beam.debug.debugActorTimerIntervalInSec = 10 -beam.debug.actor.logDepth = 12 - -beam.debug.stuckAgentDetection { - checkIntervalMs = 200 - checkMaxNumberOfMessagesEnabled = true - defaultTimeoutMs = 60000 - enabled = true - overallSimulationTimeoutMs = 100000 - thresholds = [ - { - actorTypeToMaxNumberOfMessages { - population = 1 - rideHailAgent = 1 - transitDriverAgent = 1 - } - markAsStuckAfterMs = 20000 - triggerType = "beam.agentsim.agents.InitializeTrigger" - }, - { - actorTypeToMaxNumberOfMessages { - population = 11 - } - markAsStuckAfterMs = 20000 - triggerType = "beam.agentsim.agents.PersonAgent$ActivityEndTrigger" - }, - { - actorTypeToMaxNumberOfMessages { - population = 1 - } - markAsStuckAfterMs = 20000 - triggerType = "beam.agentsim.agents.PersonAgent$ActivityStartTrigger" - }, - { - actorTypeToMaxNumberOfMessages { - population = 60 - } - markAsStuckAfterMs = 20000 - triggerType = "beam.agentsim.agents.PersonAgent$PersonDepartureTrigger" - }, - { - actorTypeToMaxNumberOfMessages { - population = 20 - } - markAsStuckAfterMs = 20000 - triggerType = "beam.agentsim.agents.modalbehaviors.DrivesVehicle$AlightVehicleTrigger" - }, - { - actorTypeToMaxNumberOfMessages { - population = 20 - } - markAsStuckAfterMs = 20000 - triggerType = "beam.agentsim.agents.modalbehaviors.DrivesVehicle$BoardVehicleTrigger" - }, - { - actorTypeToMaxNumberOfMessages { - population = 80 - rideHailAgent = 400 - transitDriverAgent = 114 - } - markAsStuckAfterMs = 20000 - triggerType = "beam.agentsim.agents.modalbehaviors.DrivesVehicle$EndLegTrigger" - }, - { - actorTypeToMaxNumberOfMessages { - population = 80 - rideHailAgent = 400 - transitDriverAgent = 114 - } - markAsStuckAfterMs = 20000 - triggerType = "beam.agentsim.agents.modalbehaviors.DrivesVehicle$StartLegTrigger" - }, - { - actorTypeToMaxNumberOfMessages { - transitDriverAgent = 1 - } - markAsStuckAfterMs = 20000 - triggerType = "beam.agentsim.scheduler.BeamAgentScheduler$KillTrigger" - - } - ] -} -################################################################## -# SPATIAL -################################################################## -beam.spatial = { - localCRS = "epsg:32631" # what crs to use for distance calculations, must be in units of meters - boundingBoxBuffer = 10000 # meters of buffer around network for defining extend of spatial indices -} - -################################################################## -# BEAM ROUTING SERVICE -################################################################## -beam.routing { - #Base local date in ISO 8061 YYYY-MM-DDTHH:MM:SS+HH:MM - baseDate = "2016-10-17T00:00:00-07:00" - transitOnStreetNetwork = true # PathTraversalEvents for transit vehicles - r5 { - directory = ${beam.inputDirectory}"/r5" - # Departure window in min - departureWindow = 1.0167 - osmFile = ${beam.inputDirectory}"/r5/beamville.osm.pbf" - osmMapdbFile = ${beam.inputDirectory}"/r5/osm.mapdb" - mNetBuilder.fromCRS = "epsg:4326" # WGS84 - mNetBuilder.toCRS = ${beam.spatial.localCRS} - } - startingIterationForTravelTimesMSA = 1 -} - -################################################################## -# Calibration -################################################################## -beam.calibration.objectiveFunction = "ModeChoiceObjectiveFunction" -beam.calibration.mode.benchmarkFilePath=${beam.inputDirectory}"/calibration/benchmark.csv" -beam.calibration.counts { - countsScaleFactor = 10.355 - writeCountsInterval = 0 - averageCountsOverIterations = ${beam.outputs.defaultWriteInterval} -} - -beam.outputs.defaultWriteInterval = 1 -beam.outputs.writePlansInterval = ${beam.outputs.defaultWriteInterval} -beam.outputs.writeEventsInterval = ${beam.outputs.defaultWriteInterval} -beam.physsim.writeEventsInterval = ${beam.outputs.defaultWriteInterval} -beam.physsim.writePlansInterval = ${beam.outputs.defaultWriteInterval} - -beam.agentsim.agents.population.useVehicleSampling = "true" - -beam.agentsim.agents.rideHail.initialization.procedural.fractionOfInitialVehicleFleet = 0.1 - -beam.debug.messageLogging = true - -beam.agentsim.agents.vehicles.dummySharedCar.vehicleTypeId = "sharedVehicle-sharedCar" - - From 228c0016d06088569af044dba86f1af6694282a2 Mon Sep 17 00:00:00 2001 From: Alvin Lee Jin Wen Date: Fri, 2 Sep 2022 17:22:08 +0800 Subject: [PATCH 4/5] Integration Test draft for FromFileVehicleAdjustment --- .../scenario/UrbanSimScenarioLoaderTest.scala | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/test/scala/beam/utils/scenario/UrbanSimScenarioLoaderTest.scala b/src/test/scala/beam/utils/scenario/UrbanSimScenarioLoaderTest.scala index 57b1686d642..247b68d8223 100644 --- a/src/test/scala/beam/utils/scenario/UrbanSimScenarioLoaderTest.scala +++ b/src/test/scala/beam/utils/scenario/UrbanSimScenarioLoaderTest.scala @@ -1,15 +1,23 @@ package beam.utils.scenario +import beam.agentsim.agents.vehicles.{BeamVehicle, BeamVehicleType} +import beam.agentsim.agents.vehicles.VehicleCategory.Bike import beam.sim.BeamScenario +import beam.sim.RunBeam.{buildUrbansimV2ScenarioSource, loadScenario} import beam.sim.common.GeoUtilsImpl -import beam.sim.config.BeamConfig +import beam.sim.config.{BeamConfig, MatSimBeamConfigBuilder} import beam.utils.TestConfigUtils.testConfig -import org.matsim.core.scenario.MutableScenario +import com.typesafe.config.ConfigFactory +import org.matsim.api.core.v01.Id +import org.matsim.core.scenario.{MutableScenario, ScenarioBuilder} +import org.matsim.households.Household import org.mockito.Mockito.{mock, when} import org.scalatest.wordspec.AsyncWordSpec import org.scalatest.BeforeAndAfterEach import org.scalatest.matchers.should.Matchers +import scala.collection.convert.ImplicitConversions.`collection AsScalaIterable` + class UrbanSimScenarioLoaderTest extends AsyncWordSpec with Matchers with BeforeAndAfterEach { private val mutableScenario = mock(classOf[MutableScenario]) private val beamScenario = mock(classOf[BeamScenario]) @@ -90,11 +98,45 @@ class UrbanSimScenarioLoaderTest extends AsyncWordSpec with Matchers with Before assertCarNumbers(res, "1" -> 2, "2" -> 2, "3" -> 2) } + + } + + "UrbanSimScenarioLoader with vehicleAdjustmentMethod = STATIC_FROM_FILE "should { + "assign vehicles properly in case1" in { + + val matsimConfig = new MatSimBeamConfigBuilder(staticVehiclesConfig).buildMatSimConf() + val emptyScenario = ScenarioBuilder(matsimConfig, beamScenario.network).build + val staticVehicleBeamConfig = BeamConfig(staticVehiclesConfig) + val staticGeoUtils = new GeoUtilsImpl(staticVehicleBeamConfig); + when(beamScenario.beamConfig).thenReturn(staticVehicleBeamConfig); + lazy val staticBeamScenario: BeamScenario = loadScenario(staticVehicleBeamConfig); + val staticScenarioSource = buildUrbansimV2ScenarioSource(staticGeoUtils, staticVehicleBeamConfig); + val urbanSimScenario = new UrbanSimScenarioLoader(emptyScenario, staticBeamScenario, staticScenarioSource, geoUtils) + urbanSimScenario.loadScenario() + + val vehicleIds = emptyScenario.getHouseholds.getHouseholds.get(Id.create(2, classOf[Household])).getVehicleIds + val vehicleMap = staticBeamScenario.privateVehicles.toMap + val vehiclesBelongToSpecificHousehold = vehicleIds.map(x => Id.create(x, classOf[BeamVehicle])).flatMap(x => vehicleMap get x); + vehiclesBelongToSpecificHousehold.count(x => x.beamVehicleType.id.compareTo( + Id.create("Bicycle", classOf[BeamVehicleType]) + ) == 0) shouldBe 7 + } + } override protected def beforeEach(): Unit = idIter = Iterator.from(1) + def staticVehiclesConfig: com.typesafe.config.Config = + ConfigFactory + .parseString(s""" + |beam.agentsim.simulationName = "beamville-urbansimv2_static" + |beam.agentsim.agents.vehicles.vehiclesFilePath = $${beam.inputDirectory}"/vehicles-test.csv" + |beam.agentsim.agents.vehicles.vehicleAdjustmentMethod = "STATIC_FROM_FILE" + """.stripMargin) + .withFallback(testConfig("test/input/beamville/beam-urbansimv2.conf")) + .resolve() + private def getConfig(fractionOfInitialVehicleFleet: Double = 1.0) = beamConfigBase.copy( matsim = beamConfigBase.matsim .copy( From 0e919a6b10580d5f5fb3290b34ee02b07adf1adf Mon Sep 17 00:00:00 2001 From: Alvin Lee Jin Wen Date: Fri, 2 Sep 2022 20:53:30 +0800 Subject: [PATCH 5/5] clean up test --- src/main/scala/beam/sim/BeamHelper.scala | 37 ++++++++++--------- .../scenario/UrbanSimScenarioLoaderTest.scala | 25 +++++++------ 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/main/scala/beam/sim/BeamHelper.scala b/src/main/scala/beam/sim/BeamHelper.scala index ef25b9d01a4..f94e95cdf30 100755 --- a/src/main/scala/beam/sim/BeamHelper.scala +++ b/src/main/scala/beam/sim/BeamHelper.scala @@ -801,6 +801,24 @@ trait BeamHelper extends LazyLogging with BeamValidationHelper { .foreach(scenario.getPopulation.removePerson) } } + def buildUrbansimV2ScenarioSource(geoUtils: GeoUtils, beamConfig: BeamConfig) = { + val pathToHouseholds = s"${beamConfig.beam.exchange.scenario.folder}/households.csv.gz" + val pathToPersonFile = s"${beamConfig.beam.exchange.scenario.folder}/persons.csv.gz" + val pathToPlans = s"${beamConfig.beam.exchange.scenario.folder}/plans.csv.gz" + val pathToBlocks = s"${beamConfig.beam.exchange.scenario.folder}/blocks.csv.gz" + new UrbansimReaderV2( + inputPersonPath = pathToPersonFile, + inputPlanPath = pathToPlans, + inputHouseholdPath = pathToHouseholds, + inputBlockPath = pathToBlocks, + geoUtils, + shouldConvertWgs2Utm = beamConfig.beam.exchange.scenario.convertWgs2Utm, + modeMap = BeamConfigUtils.parseListToMap( + beamConfig.beam.exchange.scenario.modeMap + .getOrElse(throw new RuntimeException("beam.exchange.scenario.modeMap must be set")) + ) + ) + } protected def buildBeamServicesAndScenario( beamConfig: BeamConfig, @@ -820,24 +838,7 @@ trait BeamHelper extends LazyLogging with BeamValidationHelper { val (scenario, plansMerged) = { val source = src match { case "urbansim" => buildUrbansimScenarioSource(geoUtils, beamConfig) - case "urbansim_v2" => { - val pathToHouseholds = s"${beamConfig.beam.exchange.scenario.folder}/households.csv.gz" - val pathToPersonFile = s"${beamConfig.beam.exchange.scenario.folder}/persons.csv.gz" - val pathToPlans = s"${beamConfig.beam.exchange.scenario.folder}/plans.csv.gz" - val pathToBlocks = s"${beamConfig.beam.exchange.scenario.folder}/blocks.csv.gz" - new UrbansimReaderV2( - inputPersonPath = pathToPersonFile, - inputPlanPath = pathToPlans, - inputHouseholdPath = pathToHouseholds, - inputBlockPath = pathToBlocks, - geoUtils, - shouldConvertWgs2Utm = beamConfig.beam.exchange.scenario.convertWgs2Utm, - modeMap = BeamConfigUtils.parseListToMap( - beamConfig.beam.exchange.scenario.modeMap - .getOrElse(throw new RuntimeException("beam.exchange.scenario.modeMap must be set")) - ) - ) - } + case "urbansim_v2" => buildUrbansimV2ScenarioSource(geoUtils, beamConfig) case "generic" => { val pathToHouseholds = s"${beamConfig.beam.exchange.scenario.folder}/households.csv.gz" val pathToPersonFile = s"${beamConfig.beam.exchange.scenario.folder}/persons.csv.gz" diff --git a/src/test/scala/beam/utils/scenario/UrbanSimScenarioLoaderTest.scala b/src/test/scala/beam/utils/scenario/UrbanSimScenarioLoaderTest.scala index 247b68d8223..a56e347081f 100644 --- a/src/test/scala/beam/utils/scenario/UrbanSimScenarioLoaderTest.scala +++ b/src/test/scala/beam/utils/scenario/UrbanSimScenarioLoaderTest.scala @@ -104,6 +104,17 @@ class UrbanSimScenarioLoaderTest extends AsyncWordSpec with Matchers with Before "UrbanSimScenarioLoader with vehicleAdjustmentMethod = STATIC_FROM_FILE "should { "assign vehicles properly in case1" in { + def staticVehiclesConfig: com.typesafe.config.Config = + ConfigFactory + .parseString(s""" + |beam.agentsim.simulationName = "beamville-urbansimv2_static" + |beam.agentsim.agents.vehicles.vehiclesFilePath = $${beam.inputDirectory}"/vehicles-test.csv" + |beam.agentsim.agents.vehicles.vehicleAdjustmentMethod = "STATIC_FROM_FILE" + """.stripMargin) + .withFallback(testConfig("test/input/beamville/beam-urbansimv2.conf")) + .resolve() + + val matsimConfig = new MatSimBeamConfigBuilder(staticVehiclesConfig).buildMatSimConf() val emptyScenario = ScenarioBuilder(matsimConfig, beamScenario.network).build val staticVehicleBeamConfig = BeamConfig(staticVehiclesConfig) @@ -117,9 +128,9 @@ class UrbanSimScenarioLoaderTest extends AsyncWordSpec with Matchers with Before val vehicleIds = emptyScenario.getHouseholds.getHouseholds.get(Id.create(2, classOf[Household])).getVehicleIds val vehicleMap = staticBeamScenario.privateVehicles.toMap val vehiclesBelongToSpecificHousehold = vehicleIds.map(x => Id.create(x, classOf[BeamVehicle])).flatMap(x => vehicleMap get x); - vehiclesBelongToSpecificHousehold.count(x => x.beamVehicleType.id.compareTo( + vehiclesBelongToSpecificHousehold.count(x => x.beamVehicleType.id.equals( Id.create("Bicycle", classOf[BeamVehicleType]) - ) == 0) shouldBe 7 + )) shouldBe 7 } } @@ -127,16 +138,6 @@ class UrbanSimScenarioLoaderTest extends AsyncWordSpec with Matchers with Before override protected def beforeEach(): Unit = idIter = Iterator.from(1) - def staticVehiclesConfig: com.typesafe.config.Config = - ConfigFactory - .parseString(s""" - |beam.agentsim.simulationName = "beamville-urbansimv2_static" - |beam.agentsim.agents.vehicles.vehiclesFilePath = $${beam.inputDirectory}"/vehicles-test.csv" - |beam.agentsim.agents.vehicles.vehicleAdjustmentMethod = "STATIC_FROM_FILE" - """.stripMargin) - .withFallback(testConfig("test/input/beamville/beam-urbansimv2.conf")) - .resolve() - private def getConfig(fractionOfInitialVehicleFleet: Double = 1.0) = beamConfigBase.copy( matsim = beamConfigBase.matsim .copy(