diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index e8a9b0be1..4c1bce047 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -13,9 +13,9 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v1 with: - java-version: 1.11 + java-version: 17 - name: Build with Maven run: mvn test -B -Dmatsim.preferLocalDtds=true diff --git a/CHANGELOG.md b/CHANGELOG.md index c8127cf74..ffdae9cf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ included in the (note yet determined) next version number. **Development version** +- Updated to MATSim 15 +- Improve emissions tools and add tests - Add support for multi-stage taxi trips in Sao Paulo - fix: make compatible with downstream population pipelines - Ensure outside activity id doesn't already exist diff --git a/core/src/main/java/org/eqasim/core/analysis/run/RunLegAnalysis.java b/core/src/main/java/org/eqasim/core/analysis/run/RunLegAnalysis.java index d95427ef0..8c6d6d4c9 100644 --- a/core/src/main/java/org/eqasim/core/analysis/run/RunLegAnalysis.java +++ b/core/src/main/java/org/eqasim/core/analysis/run/RunLegAnalysis.java @@ -6,7 +6,8 @@ import java.util.Optional; import java.util.stream.Collectors; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eqasim.core.analysis.DefaultPersonAnalysisFilter; import org.eqasim.core.analysis.DistanceUnit; import org.eqasim.core.analysis.PersonAnalysisFilter; @@ -28,7 +29,7 @@ import org.matsim.facilities.MatsimFacilitiesReader; public class RunLegAnalysis { - private final static Logger logger = Logger.getLogger(RunLegAnalysis.class); + private final static Logger logger = LogManager.getLogger(RunLegAnalysis.class); static public void main(String[] args) throws IOException, ConfigurationException { CommandLine cmd = new CommandLine.Builder(args) // diff --git a/core/src/main/java/org/eqasim/core/analysis/run/RunTripAnalysis.java b/core/src/main/java/org/eqasim/core/analysis/run/RunTripAnalysis.java index fb04de0d3..93996ea52 100644 --- a/core/src/main/java/org/eqasim/core/analysis/run/RunTripAnalysis.java +++ b/core/src/main/java/org/eqasim/core/analysis/run/RunTripAnalysis.java @@ -6,7 +6,8 @@ import java.util.Optional; import java.util.stream.Collectors; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eqasim.core.analysis.DefaultPersonAnalysisFilter; import org.eqasim.core.analysis.DistanceUnit; import org.eqasim.core.analysis.PersonAnalysisFilter; @@ -30,7 +31,7 @@ import org.matsim.facilities.MatsimFacilitiesReader; public class RunTripAnalysis { - private final static Logger logger = Logger.getLogger(RunTripAnalysis.class); + private final static Logger logger = LogManager.getLogger(RunTripAnalysis.class); static public void main(String[] args) throws IOException, ConfigurationException { CommandLine cmd = new CommandLine.Builder(args) // diff --git a/core/src/main/java/org/eqasim/core/analysis/trips/TripListener.java b/core/src/main/java/org/eqasim/core/analysis/trips/TripListener.java index 812f9fd0d..acad42c8e 100644 --- a/core/src/main/java/org/eqasim/core/analysis/trips/TripListener.java +++ b/core/src/main/java/org/eqasim/core/analysis/trips/TripListener.java @@ -94,7 +94,7 @@ public void handleEvent(ActivityEndEvent event) { public void handleEvent(PersonDepartureEvent event) { if (personFilter.analyzePerson(event.getPersonId())) { Leg leg = factory.createLeg(event.getLegMode()); - leg.getAttributes().putAttribute("routingMode", event.getRoutingMode()); + leg.setRoutingMode(event.getRoutingMode()); ongoing.get(event.getPersonId()).elements.add(leg); } } diff --git a/core/src/main/java/org/eqasim/core/components/headway/HeadwayCalculator.java b/core/src/main/java/org/eqasim/core/components/headway/HeadwayCalculator.java index 94ee33343..cae3293f8 100644 --- a/core/src/main/java/org/eqasim/core/components/headway/HeadwayCalculator.java +++ b/core/src/main/java/org/eqasim/core/components/headway/HeadwayCalculator.java @@ -4,6 +4,8 @@ import org.matsim.facilities.Facility; import org.matsim.utils.objectattributes.attributable.Attributes; +import org.matsim.utils.objectattributes.attributable.AttributesImpl; +import org.matsim.utils.objectattributes.attributable.AttributesUtils; import ch.sbb.matsim.routing.pt.raptor.RaptorRoute; import ch.sbb.matsim.routing.pt.raptor.RaptorRoute.RoutePart; @@ -26,7 +28,7 @@ public double calculateHeadway_min(Facility originFacility, Facility destination double latestDepartureTime = departureTime + afterDepartureOffset; List routes = raptor.calcRoutes(originFacility, destinationFacilty, earliestDepartureTime, - departureTime, latestDepartureTime, null, new Attributes()); + departureTime, latestDepartureTime, null, new AttributesImpl()); int numberOfPtRoutes = 0; diff --git a/core/src/main/java/org/eqasim/core/components/transit/events/PublicTransitEvent.java b/core/src/main/java/org/eqasim/core/components/transit/events/PublicTransitEvent.java index 0270e8f87..ebb9ea369 100644 --- a/core/src/main/java/org/eqasim/core/components/transit/events/PublicTransitEvent.java +++ b/core/src/main/java/org/eqasim/core/components/transit/events/PublicTransitEvent.java @@ -4,8 +4,8 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.events.GenericEvent; +import org.matsim.api.core.v01.events.HasPersonId; import org.matsim.api.core.v01.population.Person; -import org.matsim.core.api.internal.HasPersonId; import org.matsim.pt.transitSchedule.api.TransitLine; import org.matsim.pt.transitSchedule.api.TransitRoute; import org.matsim.pt.transitSchedule.api.TransitStopFacility; diff --git a/core/src/main/java/org/eqasim/core/misc/ParallelProgress.java b/core/src/main/java/org/eqasim/core/misc/ParallelProgress.java index d376043ef..2d7f32601 100644 --- a/core/src/main/java/org/eqasim/core/misc/ParallelProgress.java +++ b/core/src/main/java/org/eqasim/core/misc/ParallelProgress.java @@ -1,9 +1,10 @@ package org.eqasim.core.misc; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class ParallelProgress { - private final Logger logger = Logger.getLogger(ParallelProgress.class); + private final Logger logger = LogManager.getLogger(ParallelProgress.class); private final Thread thread; private final long totalCount; diff --git a/core/src/main/java/org/eqasim/core/scenario/cutter/facilities/FacilitiesCutter.java b/core/src/main/java/org/eqasim/core/scenario/cutter/facilities/FacilitiesCutter.java index 6f2d99e2e..1c54bbfb1 100644 --- a/core/src/main/java/org/eqasim/core/scenario/cutter/facilities/FacilitiesCutter.java +++ b/core/src/main/java/org/eqasim/core/scenario/cutter/facilities/FacilitiesCutter.java @@ -4,7 +4,8 @@ import java.util.HashSet; import java.util.Iterator; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eqasim.core.scenario.cutter.extent.ScenarioExtent; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Activity; @@ -16,7 +17,7 @@ import org.matsim.facilities.ActivityFacility; public class FacilitiesCutter { - private final static Logger log = Logger.getLogger(FacilitiesCutter.class); + private final static Logger log = LogManager.getLogger(FacilitiesCutter.class); private final ScenarioExtent extent; private final Collection> usedFacilityIds = new HashSet<>(); diff --git a/core/src/main/java/org/eqasim/core/scenario/cutter/network/NetworkCutter.java b/core/src/main/java/org/eqasim/core/scenario/cutter/network/NetworkCutter.java index 7b49c49b1..6496b7ca9 100644 --- a/core/src/main/java/org/eqasim/core/scenario/cutter/network/NetworkCutter.java +++ b/core/src/main/java/org/eqasim/core/scenario/cutter/network/NetworkCutter.java @@ -8,7 +8,8 @@ import java.util.Optional; import java.util.Set; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eqasim.core.scenario.cutter.extent.ScenarioExtent; import org.eqasim.core.scenario.cutter.extent.ShapeScenarioExtent; import org.matsim.api.core.v01.Id; @@ -36,7 +37,7 @@ import org.matsim.pt.transitSchedule.api.TransitStopFacility; public class NetworkCutter { - private final static Logger log = Logger.getLogger(NetworkCutter.class); + private final static Logger log = LogManager.getLogger(NetworkCutter.class); private final ScenarioExtent extent; private final MinimumNetworkFinder minimumNetworkFinder; diff --git a/core/src/main/java/org/eqasim/core/scenario/cutter/transit/TransitScheduleCutter.java b/core/src/main/java/org/eqasim/core/scenario/cutter/transit/TransitScheduleCutter.java index b8151b3cc..d940a5eb6 100644 --- a/core/src/main/java/org/eqasim/core/scenario/cutter/transit/TransitScheduleCutter.java +++ b/core/src/main/java/org/eqasim/core/scenario/cutter/transit/TransitScheduleCutter.java @@ -7,7 +7,8 @@ import java.util.Set; import java.util.stream.Collectors; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eqasim.core.scenario.cutter.extent.ScenarioExtent; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; @@ -25,7 +26,7 @@ import org.matsim.pt.transitSchedule.api.TransitStopFacility; public class TransitScheduleCutter { - private final static Logger log = Logger.getLogger(TransitScheduleCutter.class); + private final static Logger log = LogManager.getLogger(TransitScheduleCutter.class); private final ScenarioExtent extent; private final StopSequenceCrossingPointFinder crossingPointFinder; diff --git a/core/src/main/java/org/eqasim/core/scenario/cutter/transit/TransitVehiclesCutter.java b/core/src/main/java/org/eqasim/core/scenario/cutter/transit/TransitVehiclesCutter.java index ef15d0370..be6a844f5 100644 --- a/core/src/main/java/org/eqasim/core/scenario/cutter/transit/TransitVehiclesCutter.java +++ b/core/src/main/java/org/eqasim/core/scenario/cutter/transit/TransitVehiclesCutter.java @@ -3,7 +3,8 @@ import java.util.HashSet; import java.util.Set; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.matsim.pt.transitSchedule.api.Departure; import org.matsim.pt.transitSchedule.api.TransitLine; import org.matsim.pt.transitSchedule.api.TransitRoute; @@ -12,7 +13,7 @@ import org.matsim.vehicles.Vehicles; public class TransitVehiclesCutter { - private final static Logger log = Logger.getLogger(TransitVehiclesCutter.class); + private final static Logger log = LogManager.getLogger(TransitVehiclesCutter.class); private final TransitSchedule schedule; diff --git a/core/src/main/java/org/eqasim/core/scenario/preparation/AdjustLinkLength.java b/core/src/main/java/org/eqasim/core/scenario/preparation/AdjustLinkLength.java index 9cc99520e..da9e61013 100644 --- a/core/src/main/java/org/eqasim/core/scenario/preparation/AdjustLinkLength.java +++ b/core/src/main/java/org/eqasim/core/scenario/preparation/AdjustLinkLength.java @@ -1,12 +1,13 @@ package org.eqasim.core.scenario.preparation; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; import org.matsim.core.utils.geometry.CoordUtils; public class AdjustLinkLength { - private final Logger logger = Logger.getLogger(AdjustLinkLength.class); + private final Logger logger = LogManager.getLogger(AdjustLinkLength.class); public void run(Network network) { int infiniteSpeedCount = 0; diff --git a/core/src/main/java/org/eqasim/core/scenario/validation/ScenarioValidator.java b/core/src/main/java/org/eqasim/core/scenario/validation/ScenarioValidator.java index 7d33003c0..7e6751c17 100644 --- a/core/src/main/java/org/eqasim/core/scenario/validation/ScenarioValidator.java +++ b/core/src/main/java/org/eqasim/core/scenario/validation/ScenarioValidator.java @@ -1,6 +1,7 @@ package org.eqasim.core.scenario.validation; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Link; @@ -15,7 +16,7 @@ import org.matsim.facilities.ActivityFacility; public class ScenarioValidator { - private final static Logger logger = Logger.getLogger(ScenarioValidator.class); + private final static Logger logger = LogManager.getLogger(ScenarioValidator.class); public boolean checkSpatialConsistency(Scenario scenario) { boolean errorsFound = false; diff --git a/core/src/main/java/org/eqasim/core/simulation/calibration/CalibrationOutputListener.java b/core/src/main/java/org/eqasim/core/simulation/calibration/CalibrationOutputListener.java index c5b8e761b..569d335e0 100644 --- a/core/src/main/java/org/eqasim/core/simulation/calibration/CalibrationOutputListener.java +++ b/core/src/main/java/org/eqasim/core/simulation/calibration/CalibrationOutputListener.java @@ -9,7 +9,8 @@ import java.io.OutputStreamWriter; import java.nio.file.Files; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eqasim.core.analysis.trips.TripListener; import org.eqasim.core.components.config.EqasimConfigGroup; import org.matsim.core.config.groups.ControlerConfigGroup; @@ -25,7 +26,7 @@ @Singleton public class CalibrationOutputListener implements IterationEndsListener, ShutdownListener { - private final Logger logger = Logger.getLogger(CalibrationOutputListener.class); + private final Logger logger = LogManager.getLogger(CalibrationOutputListener.class); private static final String OUTPUT_FILE_NAME_JSON = "calibration.json"; private static final String OUTPUT_FILE_NAME_HTML = "calibration.html"; diff --git a/core/src/main/java/org/eqasim/core/simulation/mode_choice/ParameterDefinition.java b/core/src/main/java/org/eqasim/core/simulation/mode_choice/ParameterDefinition.java index 515cec1fd..ee1dd11b8 100644 --- a/core/src/main/java/org/eqasim/core/simulation/mode_choice/ParameterDefinition.java +++ b/core/src/main/java/org/eqasim/core/simulation/mode_choice/ParameterDefinition.java @@ -6,7 +6,8 @@ import java.util.HashMap; import java.util.Map; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.matsim.core.config.CommandLine; import org.matsim.core.config.CommandLine.ConfigurationException; @@ -16,7 +17,7 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; public interface ParameterDefinition { - final static Logger logger = Logger.getLogger(ParameterDefinition.class); + final static Logger logger = LogManager.getLogger(ParameterDefinition.class); static public void applyCommandLine(String prefix, CommandLine cmd, ParameterDefinition parameterDefinition) { Map values = new HashMap<>(); diff --git a/core/src/main/java/org/eqasim/core/simulation/mode_choice/epsilon/EpsilonModule.java b/core/src/main/java/org/eqasim/core/simulation/mode_choice/epsilon/EpsilonModule.java index d80135491..0389748c1 100644 --- a/core/src/main/java/org/eqasim/core/simulation/mode_choice/epsilon/EpsilonModule.java +++ b/core/src/main/java/org/eqasim/core/simulation/mode_choice/epsilon/EpsilonModule.java @@ -3,7 +3,8 @@ import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Provides; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eqasim.core.components.config.EqasimConfigGroup; import org.eqasim.core.simulation.mode_choice.AbstractEqasimExtension; import org.eqasim.core.simulation.mode_choice.utilities.UtilityEstimator; @@ -15,7 +16,7 @@ public class EpsilonModule extends AbstractEqasimExtension { - public static final Logger logger = Logger.getLogger(EpsilonModule.class); + public static final Logger logger = LogManager.getLogger(EpsilonModule.class); public static final String EPSILON_UTILITY_PREFIX = "epsilon_"; @Provides diff --git a/core/src/main/java/org/eqasim/core/simulation/modes/drt/utils/AdaptConfigForDrt.java b/core/src/main/java/org/eqasim/core/simulation/modes/drt/utils/AdaptConfigForDrt.java index 00c37cd48..d36d9e62a 100644 --- a/core/src/main/java/org/eqasim/core/simulation/modes/drt/utils/AdaptConfigForDrt.java +++ b/core/src/main/java/org/eqasim/core/simulation/modes/drt/utils/AdaptConfigForDrt.java @@ -57,29 +57,29 @@ public static void adapt(Config config, Map vehiclesPathByDrtMod for(String drtMode: vehiclesPathByDrtMode.keySet()) { DrtConfigGroup drtConfigGroup = new DrtConfigGroup(); - drtConfigGroup.setMode(drtMode); - drtConfigGroup.setOperationalScheme(DrtConfigGroup.OperationalScheme.valueOf(operationalSchemes.get(drtMode))); - drtConfigGroup.setStopDuration(15.0); - drtConfigGroup.setMaxWaitTime(600); - drtConfigGroup.setMaxTravelTimeAlpha(1.5); - drtConfigGroup.setMaxTravelTimeBeta(300.0); - drtConfigGroup.setVehiclesFile(vehiclesPathByDrtMode.get(drtMode)); + drtConfigGroup.mode = drtMode; + drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.valueOf(operationalSchemes.get(drtMode)); + drtConfigGroup.stopDuration = 15.0; + drtConfigGroup.maxWaitTime = 600; + drtConfigGroup.maxTravelTimeAlpha = 1.5; + drtConfigGroup.maxTravelTimeBeta = 300.0; + drtConfigGroup.vehiclesFile = vehiclesPathByDrtMode.get(drtMode); DrtInsertionSearchParams searchParams = new ExtensiveInsertionSearchParams(); drtConfigGroup.addDrtInsertionSearchParams(searchParams); RebalancingParams rebalancingParams = new RebalancingParams(); - rebalancingParams.setInterval(1800); + rebalancingParams.interval =1800; rebalancingParams.addParameterSet(new PlusOneRebalancingStrategyParams()); drtConfigGroup.addParameterSet(rebalancingParams); DrtZonalSystemParams drtZonalSystemParams = new DrtZonalSystemParams(); - drtZonalSystemParams.setZonesGeneration(DrtZonalSystemParams.ZoneGeneration.GridFromNetwork); - drtZonalSystemParams.setCellSize(500.0); - drtZonalSystemParams.setTargetLinkSelection(DrtZonalSystemParams.TargetLinkSelection.mostCentral); + drtZonalSystemParams.zonesGeneration = DrtZonalSystemParams.ZoneGeneration.GridFromNetwork; + drtZonalSystemParams.cellSize = 500.0; + drtZonalSystemParams.targetLinkSelection = DrtZonalSystemParams.TargetLinkSelection.mostCentral; drtConfigGroup.addParameterSet(drtZonalSystemParams); - multiModeDrtConfigGroup.addDrtConfig(drtConfigGroup); + multiModeDrtConfigGroup.addParameterSet(drtConfigGroup); // Set up choice model EqasimConfigGroup eqasimConfig = EqasimConfigGroup.get(config); diff --git a/core/src/main/java/org/eqasim/core/simulation/modes/drt/utils/CreateDrtVehicles.java b/core/src/main/java/org/eqasim/core/simulation/modes/drt/utils/CreateDrtVehicles.java index feda7e3a4..24e7a88ca 100644 --- a/core/src/main/java/org/eqasim/core/simulation/modes/drt/utils/CreateDrtVehicles.java +++ b/core/src/main/java/org/eqasim/core/simulation/modes/drt/utils/CreateDrtVehicles.java @@ -1,6 +1,7 @@ package org.eqasim.core.simulation.modes.drt.utils; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; @@ -15,7 +16,7 @@ import java.util.Random; public class CreateDrtVehicles { - private final static Logger logger = Logger.getLogger(CreateDrtVehicles.class); + private final static Logger logger = LogManager.getLogger(CreateDrtVehicles.class); public final static long DEFAULT_RANDOM_SEED = 1234; diff --git a/core/src/main/java/org/eqasim/core/tools/RemovePersonsWithActivityTypes.java b/core/src/main/java/org/eqasim/core/tools/RemovePersonsWithActivityTypes.java index 32e5e2691..c7f00bd57 100644 --- a/core/src/main/java/org/eqasim/core/tools/RemovePersonsWithActivityTypes.java +++ b/core/src/main/java/org/eqasim/core/tools/RemovePersonsWithActivityTypes.java @@ -1,6 +1,7 @@ package org.eqasim.core.tools; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Identifiable; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.population.Activity; @@ -16,7 +17,7 @@ public class RemovePersonsWithActivityTypes { - private static final Logger logger = Logger.getLogger(RemovePersonsWithActivityTypes.class); + private static final Logger logger = LogManager.getLogger(RemovePersonsWithActivityTypes.class); public static void main(String[] args) throws CommandLine.ConfigurationException { CommandLine commandLine = new CommandLine.Builder(args).requireOptions("input-path", "output-path", "activity-types").build(); diff --git a/core/src/main/java/org/eqasim/core/tools/routing/RunBatchPublicTransportRouter.java b/core/src/main/java/org/eqasim/core/tools/routing/RunBatchPublicTransportRouter.java index 410382945..fecaf654c 100644 --- a/core/src/main/java/org/eqasim/core/tools/routing/RunBatchPublicTransportRouter.java +++ b/core/src/main/java/org/eqasim/core/tools/routing/RunBatchPublicTransportRouter.java @@ -11,7 +11,8 @@ import java.util.Set; import org.apache.commons.lang3.tuple.Pair; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eqasim.core.components.headway.HeadwayCalculator; import org.eqasim.core.components.headway.HeadwayImputerModule; import org.eqasim.core.misc.InjectorBuilder; @@ -50,7 +51,7 @@ import ch.sbb.matsim.config.SwissRailRaptorConfigGroup; public class RunBatchPublicTransportRouter { - private final static Logger logger = Logger.getLogger(RunBatchPublicTransportRouter.class); + private final static Logger logger = LogManager.getLogger(RunBatchPublicTransportRouter.class); static public void main(String[] args) throws ConfigurationException, JsonGenerationException, JsonMappingException, IOException, InterruptedException { diff --git a/core/src/test/java/org/eqasim/mode_choice/TestSpecialModeChoiceCases.java b/core/src/test/java/org/eqasim/mode_choice/TestSpecialModeChoiceCases.java index 3be25b238..3eeecc6f1 100644 --- a/core/src/test/java/org/eqasim/mode_choice/TestSpecialModeChoiceCases.java +++ b/core/src/test/java/org/eqasim/mode_choice/TestSpecialModeChoiceCases.java @@ -45,7 +45,7 @@ import org.matsim.core.router.RoutingRequest; import org.matsim.core.scenario.ScenarioUtils; import org.matsim.core.utils.timing.TimeInterpretationModule; -import org.matsim.utils.objectattributes.attributable.Attributes; +import org.matsim.utils.objectattributes.attributable.AttributesImpl; import com.google.inject.Inject; import com.google.inject.Injector; @@ -200,7 +200,7 @@ static private void appendTrip(List trips, String preced destinationActivity.setMaximumDuration(3600.0); DiscreteModeChoiceTrip trip = new DiscreteModeChoiceTrip(originActivity, destinationActivity, "walk", - Collections.emptyList(), 0, trips.size(), trips.size(), new Attributes()); + Collections.emptyList(), 0, trips.size(), trips.size(), new AttributesImpl()); trips.add(trip); } diff --git a/examples/src/main/java/org/eqasim/examples/corsica_drt/RunCorsicaDrtSimulation.java b/examples/src/main/java/org/eqasim/examples/corsica_drt/RunCorsicaDrtSimulation.java index 4ae8e557a..a06018f99 100644 --- a/examples/src/main/java/org/eqasim/examples/corsica_drt/RunCorsicaDrtSimulation.java +++ b/examples/src/main/java/org/eqasim/examples/corsica_drt/RunCorsicaDrtSimulation.java @@ -72,18 +72,18 @@ static public void main(String[] args) throws ConfigurationException { config.addModule(multiModeDrtConfig); DrtConfigGroup drtConfig = new DrtConfigGroup(); - drtConfig.setMode("drt"); - drtConfig.setOperationalScheme(OperationalScheme.door2door); - drtConfig.setStopDuration(15.0); - drtConfig.setMaxWaitTime(600.0); - drtConfig.setMaxTravelTimeAlpha(1.5); - drtConfig.setMaxTravelTimeBeta(300.0); - drtConfig.setVehiclesFile(Resources.getResource("corsica_drt/drt_vehicles.xml").toString()); + drtConfig.mode = "drt"; + drtConfig.operationalScheme = OperationalScheme.door2door; + drtConfig.stopDuration = 15.0; + drtConfig.maxWaitTime = 3600.0; + drtConfig.maxTravelTimeAlpha = 3.0; + drtConfig.maxTravelTimeBeta = 3600.0; + drtConfig.vehiclesFile = Resources.getResource("corsica_drt/drt_vehicles.xml").toString(); DrtInsertionSearchParams searchParams = new SelectiveInsertionSearchParams(); drtConfig.addDrtInsertionSearchParams(searchParams); - multiModeDrtConfig.addDrtConfig(drtConfig); + multiModeDrtConfig.addParameterSet(drtConfig); DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.planCalcScore(), config.plansCalcRoute()); // Additional requirements diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/EmissionsByPolluant.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/EmissionsByPolluant.java deleted file mode 100644 index a229bd10a..000000000 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/EmissionsByPolluant.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.eqasim.ile_de_france.emissions; -// this is a modified copy of a private contribs.emissions class -// TODO: will need to be updated after the matsim 14 release to profit from https://github.com/matsim-org/matsim-libs/pull/1859 - -import org.matsim.contrib.emissions.Pollutant; - -import java.util.HashMap; -import java.util.Map; - -/** - * Sums up emissions by pollutant. Basically wraps a hash map but is here for better - * readability of org.matsim.contrib.emissions.analysis.EmissionsOnLinkEventHandler - */ -class EmissionsByPollutant { - // The EmissionsByPollutant potentially adds up the same emissions coming from cold and warm. Thus, this cannot be combined into the enum approach - // without some thinking. kai, jan'20 - // yyyy todo I think that this now can be done. kai, jan'20 - - private final Map emissionByPollutant; - - EmissionsByPollutant(Map emissions) { - this.emissionByPollutant = emissions; - } - - void addEmissions( Map emissions ) { - emissions.forEach(this::addEmission); - } - - double addEmission(Pollutant pollutant, double value) { - return emissionByPollutant.merge(pollutant, value, Double::sum); - } - - Map getEmissions() { - return emissionByPollutant; - } - - double getEmission(Pollutant pollutant) { - return emissionByPollutant.get(pollutant); - } - - -} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/EmissionsOnLinkEventsHandler.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/EmissionsOnLinkEventsHandler.java deleted file mode 100644 index 547b0591a..000000000 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/EmissionsOnLinkEventsHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.eqasim.ile_de_france.emissions; -// this is a modified copy of a private contribs.emissions class -// TODO: will need to be updated after the matsim 14 release to profit from https://github.com/matsim-org/matsim-libs/pull/1859 - -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Link; -import org.matsim.contrib.analysis.time.TimeBinMap; -import org.matsim.contrib.emissions.events.ColdEmissionEvent; -import org.matsim.contrib.emissions.events.ColdEmissionEventHandler; -import org.matsim.contrib.emissions.events.WarmEmissionEvent; -import org.matsim.contrib.emissions.events.WarmEmissionEventHandler; -import org.matsim.contrib.emissions.Pollutant; - -import java.util.HashMap; -import java.util.Map; - -/** - * Collects Warm- and Cold-Emission-Events by time bin and by link-id - */ -class EmissionsOnLinkEventHandler implements WarmEmissionEventHandler, ColdEmissionEventHandler { - - private final TimeBinMap, EmissionsByPollutant>> timeBins; - - EmissionsOnLinkEventHandler(double timeBinSizeInSeconds) { - - this.timeBins = new TimeBinMap<>(timeBinSizeInSeconds); - } - - /** - * Yields collected emissions - * - * @return Collected emissions by time bin and by link id - */ - TimeBinMap, EmissionsByPollutant>> getTimeBins() { - return timeBins; - } - - @Override - public void reset(int iteration) { - timeBins.clear(); - } - - @Override - public void handleEvent(WarmEmissionEvent event) { - Map map = new HashMap<>() ; - for( Map.Entry entry : event.getWarmEmissions().entrySet() ){ - map.put( entry.getKey(), entry.getValue() ) ; - } - handleEmissionEvent(event.getTime(), event.getLinkId(), map ); - } - - @Override - public void handleEvent(ColdEmissionEvent event) { - - handleEmissionEvent(event.getTime(), event.getLinkId(), event.getColdEmissions()); - } - - private void handleEmissionEvent(double time, Id linkId, Map emissions) { - - TimeBinMap.TimeBin, EmissionsByPollutant>> currentBin = timeBins.getTimeBin(time); - - if (!currentBin.hasValue()){ - currentBin.setValue( new HashMap<>() ); - } - if (!currentBin.getValue().containsKey(linkId)){ - currentBin.getValue().put( linkId, new EmissionsByPollutant( new HashMap<>( emissions ) ) ); - } else{ - currentBin.getValue().get( linkId ).addEmissions( emissions ); - } - } -} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/OsmHbefaMapping.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/OsmHbefaMapping.java deleted file mode 100644 index 6f366107b..000000000 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/OsmHbefaMapping.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.eqasim.ile_de_france.emissions; -// this is a modified copy of a private contribs.emissions class -// TODO: will need to be updated after the matsim 14 release to profit from https://github.com/matsim-org/matsim-libs/pull/1859 - -import java.util.HashMap; -import java.util.Map; - -import org.matsim.api.core.v01.network.Link; - -import com.google.inject.Provides; -import org.matsim.api.core.v01.network.Network; -import org.matsim.contrib.emissions.EmissionUtils; - -/** - * Created by molloyj on 01.12.2017. - * - * - * handled OSM road types: - * motorway,trunk,primary,secondary, tertiary, unclassified,residential,service - * motorway_link, trunk_link,primary_link, secondary_link - * tertiary_link, living_street, pedestrian,track,road - * - * Hbefa categories and respective speeds - * URB/MW-Nat./80 - 130 - * URB/MW-City/60 - 110 - * URB/Trunk-Nat./70 - 110 - * URB/Trunk-City/50 - 90 - * URB/Distr/50 - 80 - * URB/Local/50 - 60 - * URB/Access/30 - 50 - * - * Conversions from OSM to hbefa types - * motorway;MW - * primary;Trunk - * secondary;Distr - * tertiary;Local - * residential;Access - * living;Access - */ - -public class OsmHbefaMapping { - private static final int MAX_SPEED = 130; - private static final String OSM_HIGHWAY_TAG = "osm:way:highway"; - Map hbfeaMap = new HashMap<>(); - - public static class Hbefa { - String name; - int min; - int max; - - public Hbefa(String name, int min, int max) { - this.name = name; - this.min = min; - this.max = max; - } - } - - public void addHbefaMappings(Network network) { - for (Link link : network.getLinks().values()) { - String hbefaString = determineHebfaType(link); - if (hbefaString != null) { - EmissionUtils.setHbefaRoadType(link, hbefaString); - } - } - } - - @Provides - public static OsmHbefaMapping build() { - OsmHbefaMapping mapping = new OsmHbefaMapping(); - mapping.put("motorway-Nat.", new Hbefa("MW-Nat.",80,130)); - mapping.put("motorway", new Hbefa("MW-City",60,90)); - mapping.put("primary-Nat.", new Hbefa("Trunk-Nat.",80,110)); - mapping.put("primary", new Hbefa("Trunk-City",50,80)); - mapping.put("trunk", new Hbefa("Trunk-City",50,80)); - mapping.put("secondary", new Hbefa("Distr",50,80)); - mapping.put("tertiary", new Hbefa("Local",50,60)); - mapping.put("residential", new Hbefa("Access",30,50)); - mapping.put("service", new Hbefa("Access",30,50)); - mapping.put("living", new Hbefa("Access",30,50)); - - return mapping; - } - - private void put(String s, Hbefa hbefa) { - hbfeaMap.put(s, hbefa); - } - - public String determineHebfaType(Link link) { - String roadType = (String) link.getAttributes().getAttribute(OSM_HIGHWAY_TAG); - String hbefaType = null; - if (roadType != null) { - hbefaType = getHEBFAtype(roadType,link.getFreespeed()); - } - return hbefaType; - - } - - private String getHEBFAtype(String roadType, double freeVelocity) { - - - String[] ss = roadType.split("_"); //want to remove - String type = ss[0]; - - //TODO: could make distinction between national and city, based on shapefile, or regions. - double freeVelocity_kmh = freeVelocity * 3.6; - - if (type.equals("unclassified") || type.equals("road")) { - if (freeVelocity_kmh <= 50) type = "living"; - else if (freeVelocity_kmh == 60) type = "tertiary"; - else if (freeVelocity_kmh == 70) type = "secondary"; - else if (freeVelocity_kmh <= 90) type = "primary"; - else type = "motorway"; - } - - //specify that if speed > 90 and primary or motorway, then Nat. - if (type.equals("motorway") || type.equals("primary") && freeVelocity_kmh >= 90) { - type += "-Nat."; - } - if (hbfeaMap.get(type) == null) { - return null; - //throw new RuntimeException("'"+ type +"' not in hbefa map"); - } - int min_speed = hbfeaMap.get(type).min; - int max_speed = hbfeaMap.get(type).max; - int capped_speed = (int) Math.min(Math.max(min_speed, freeVelocity_kmh), max_speed); - - return "URB/" + hbfeaMap.get(type).name + "/" + capped_speed; - - - } - - -} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/RunComputeEmissionsEvents.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/RunComputeEmissionsEvents.java index 2a5a2830b..7929341f6 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/RunComputeEmissionsEvents.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/RunComputeEmissionsEvents.java @@ -1,11 +1,13 @@ package org.eqasim.ile_de_france.emissions; import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; import org.eqasim.ile_de_france.IDFConfigurator; import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; -import org.matsim.api.core.v01.network.NetworkWriter; import org.matsim.contrib.emissions.EmissionModule; +import org.matsim.contrib.emissions.OsmHbefaMapping; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.config.CommandLine; @@ -17,10 +19,9 @@ import org.matsim.core.events.EventsUtils; import org.matsim.core.events.MatsimEventsReader; import org.matsim.core.events.algorithms.EventWriterXML; +import org.matsim.core.network.NetworkUtils; import org.matsim.core.scenario.ScenarioUtils; -// TODO: will need to be updated after the matsim 14 release to profit from https://github.com/matsim-org/matsim-libs/pull/1859 - public class RunComputeEmissionsEvents { public static void main(String[] args) throws CommandLine.ConfigurationException { @@ -35,9 +36,8 @@ public static void main(String[] args) throws CommandLine.ConfigurationException Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configGroups); cmd.applyConfiguration(config); - EmissionsConfigGroup emissionsConfig = (EmissionsConfigGroup) config.getModule("emissions"); + EmissionsConfigGroup emissionsConfig = (EmissionsConfigGroup) config.getModules().get("emissions"); emissionsConfig.setHbefaVehicleDescriptionSource(EmissionsConfigGroup.HbefaVehicleDescriptionSource.asEngineInformationAttributes); - emissionsConfig.setHbefaRoadTypeSource(EmissionsConfigGroup.HbefaRoadTypeSource.fromLinkAttributes); emissionsConfig.setDetailedVsAverageLookupBehavior( EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable); emissionsConfig.setNonScenarioVehicles(EmissionsConfigGroup.NonScenarioVehicles.abort); @@ -56,6 +56,26 @@ public static void main(String[] args) throws CommandLine.ConfigurationException OsmHbefaMapping osmHbefaMapping = OsmHbefaMapping.build(); Network network = scenario.getNetwork(); + // if the network is from pt2matsim it might not have "type" but "osm:way:highway" attribute instead + for (Link link: network.getLinks().values()) { + String roadTypeAttribute = NetworkUtils.getType(link); + String osmRoadTypeAttribute = (String) link.getAttributes().getAttribute("osm:way:highway"); + if (StringUtils.isBlank(roadTypeAttribute)) { + if (!StringUtils.isBlank(osmRoadTypeAttribute)) { + NetworkUtils.setType(link, osmRoadTypeAttribute); + } + else { // not a road (railway for example) + NetworkUtils.setType(link, "unclassified"); + } + } + // '_link' types are not defined in the OSM mapping, set t undefined + if (NetworkUtils.getType(link).contains("_link")) { + NetworkUtils.setType(link, "unclassified"); + } + if (NetworkUtils.getType(link).equals("living_street")) { + NetworkUtils.setType(link, "living"); + } + } osmHbefaMapping.addHbefaMappings(network); EventsManager eventsManager = EventsUtils.createEventsManager(); diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/RunComputeEmissionsGrid.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/RunComputeEmissionsGrid.java index 1da27d2a5..e525b90b5 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/RunComputeEmissionsGrid.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/RunComputeEmissionsGrid.java @@ -15,8 +15,6 @@ import org.matsim.core.utils.gis.ShapeFileReader; import org.opengis.feature.simple.SimpleFeature; -// TODO: will need to be updated after the matsim 14 release to profit from https://github.com/matsim-org/matsim-libs/pull/1859 - public class RunComputeEmissionsGrid { public static void main(String[] args) throws CommandLine.ConfigurationException { diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/RunExportEmissionsNetwork.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/RunExportEmissionsNetwork.java index c543f01a8..2bf7b473d 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/RunExportEmissionsNetwork.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/emissions/RunExportEmissionsNetwork.java @@ -8,6 +8,8 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.analysis.time.TimeBinMap; import org.matsim.contrib.emissions.Pollutant; +import org.matsim.contrib.emissions.analysis.EmissionsByPollutant; +import org.matsim.contrib.emissions.analysis.EmissionsOnLinkEventHandler; import org.matsim.contrib.emissions.events.EmissionEventsReader; import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; import org.matsim.core.api.experimental.events.EventsManager; @@ -25,8 +27,6 @@ import java.util.*; -// TODO: will need to be updated after the matsim 14 release to profit from https://github.com/matsim-org/matsim-libs/pull/1859 - public class RunExportEmissionsNetwork { public static void main(String[] args) throws CommandLine.ConfigurationException { @@ -34,6 +34,7 @@ public static void main(String[] args) throws CommandLine.ConfigurationException CommandLine cmd = new CommandLine.Builder(args) // .requireOptions("config-path") // .allowOptions("time-bin-size") + .allowOptions("pollutants") .build(); ConfigGroup[] configGroups = ArrayUtils.addAll(new IDFConfigurator().getConfigGroups(), new EmissionsConfigGroup()); @@ -44,6 +45,8 @@ public static void main(String[] args) throws CommandLine.ConfigurationException int timeBinSize = Integer.parseInt(cmd.getOption("time-bin-size").orElse("3600")); + String[] wanted_pollutants = cmd.getOption("pollutants").orElse("PM,CO,NOx").split(","); + EventsManager eventsManager = EventsUtils.createEventsManager(); EmissionsOnLinkEventHandler handler = new EmissionsOnLinkEventHandler(timeBinSize); @@ -59,19 +62,14 @@ public static void main(String[] args) throws CommandLine.ConfigurationException Map, ? extends Link> links = network.getLinks(); TimeBinMap, EmissionsByPollutant>> res = handler.getTimeBins(); Collection features = new LinkedList<>(); - - PolylineFeatureFactory linkFactory = new PolylineFeatureFactory.Builder() // + PolylineFeatureFactory.Builder builder = new PolylineFeatureFactory.Builder() // .setCrs(MGC.getCRS("epsg:2154")).setName("Emissions") // .addAttribute("link", String.class) // - .addAttribute("time", Integer.class) // - .addAttribute("PM", Double.class) // - .addAttribute("FC", Double.class) // - .addAttribute("CO", Double.class) // - .addAttribute("FC_MJ", Double.class) // - .addAttribute("HC", Double.class) // - .addAttribute("NOx", Double.class) // - .addAttribute("CO2_rep", Double.class) // - .create(); + .addAttribute("time", Integer.class); + for (String pollutant: wanted_pollutants) { + builder.addAttribute(pollutant, Double.class); + } + PolylineFeatureFactory linkFactory = builder.create(); for (TimeBinMap.TimeBin, EmissionsByPollutant>> timeBin : res.getTimeBins()) { int startTime = (int) timeBin.getStartTime(); @@ -90,8 +88,15 @@ public static void main(String[] args) throws CommandLine.ConfigurationException attributes.add(startTime); EmissionsByPollutant emissions = entry.getValue(); Map pollutants = emissions.getEmissions(); - for (Map.Entry pollutant : pollutants.entrySet()) { - attributes.add(pollutant.getValue()); + for (String pollutant: wanted_pollutants) { + try { + Pollutant pollutant_key = Pollutant.valueOf(pollutant); + attributes.add(pollutants.getOrDefault(pollutant_key, Double.NaN)); + } + catch (IllegalArgumentException e) { + attributes.add(Double.NaN); + } + } SimpleFeature feature = linkFactory.createPolyline( // diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/standalone_mode_choice/StandaloneModeChoiceModule.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/standalone_mode_choice/StandaloneModeChoiceModule.java index 147c001b9..62d53b711 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/standalone_mode_choice/StandaloneModeChoiceModule.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/standalone_mode_choice/StandaloneModeChoiceModule.java @@ -1,43 +1,28 @@ package org.eqasim.ile_de_france.standalone_mode_choice; -import com.google.inject.Inject; -import com.google.inject.Provider; -import com.google.inject.Provides; -import com.google.inject.Singleton; -import org.apache.log4j.Logger; -import org.matsim.api.core.v01.Id; +import java.io.File; +import java.io.IOException; +import java.util.Objects; + +import javax.inject.Named; + import org.matsim.api.core.v01.Scenario; -import org.matsim.api.core.v01.population.Leg; -import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.Plan; import org.matsim.api.core.v01.population.Population; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel; import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup; import org.matsim.core.config.Config; import org.matsim.core.config.groups.ControlerConfigGroup; -import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.core.controler.OutputDirectoryLogging; -import org.matsim.core.population.routes.NetworkRoute; -import org.matsim.core.router.TripStructureUtils; import org.matsim.core.utils.io.IOUtils; -import org.matsim.vehicles.Vehicle; -import org.matsim.vehicles.VehicleUtils; -import org.matsim.vehicles.Vehicles; -import org.matsim.vehicles.VehiclesFactory; - -import javax.inject.Named; -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Provides; +import com.google.inject.Singleton; public class StandaloneModeChoiceModule extends AbstractModule { - private static final Logger log = Logger.getLogger(StandaloneModeChoiceModule.class); - private final StandaloneModeChoiceConfigGroup configGroup; private final int numberOfThreads; private final long randomSeed; diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/standalone_mode_choice/StandaloneModeChoicePerformer.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/standalone_mode_choice/StandaloneModeChoicePerformer.java index dab5afda2..edc566be6 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/standalone_mode_choice/StandaloneModeChoicePerformer.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/standalone_mode_choice/StandaloneModeChoicePerformer.java @@ -1,34 +1,34 @@ package org.eqasim.ile_de_france.standalone_mode_choice; -import com.google.inject.Provider; -import org.apache.log4j.Logger; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eqasim.core.scenario.routing.RunPopulationRouting; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.IdSet; import org.matsim.api.core.v01.Scenario; -import org.matsim.api.core.v01.population.*; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.Plan; +import org.matsim.api.core.v01.population.Population; +import org.matsim.api.core.v01.population.PopulationWriter; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceModel; import org.matsim.contribs.discrete_mode_choice.replanning.DiscreteModeChoiceAlgorithm; import org.matsim.contribs.discrete_mode_choice.replanning.TripListConverter; -import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.controler.OutputDirectoryHierarchy; -import org.matsim.core.population.routes.NetworkRoute; -import org.matsim.core.router.TripStructureUtils; import org.matsim.core.utils.misc.Counter; -import org.matsim.vehicles.Vehicle; -import org.matsim.vehicles.VehicleUtils; -import org.matsim.vehicles.Vehicles; -import org.matsim.vehicles.VehiclesFactory; -import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; +import com.google.inject.Provider; public class StandaloneModeChoicePerformer { - private static final Logger logger = Logger.getLogger(StandaloneModeChoicePerformer.class); + private static final Logger logger = LogManager.getLogger(StandaloneModeChoicePerformer.class); private final Provider discreteModeChoiceModelProvider; private final boolean removePersonsWithBadPlans; diff --git a/ile_de_france/src/main/resources/corsica/corsica_config.xml b/ile_de_france/src/main/resources/corsica/corsica_config.xml index 4e09c5c7e..a263b3bb2 100644 --- a/ile_de_france/src/main/resources/corsica/corsica_config.xml +++ b/ile_de_france/src/main/resources/corsica/corsica_config.xml @@ -107,6 +107,10 @@ + + + + @@ -137,14 +141,14 @@ - - + @@ -157,7 +161,7 @@ - + @@ -182,15 +186,15 @@ + + + - - - - + @@ -249,10 +253,21 @@ - - + + + + + + + + + + + + + @@ -262,7 +277,7 @@ - + @@ -275,6 +290,8 @@ + + @@ -302,7 +319,7 @@ - + @@ -512,7 +529,7 @@ - + @@ -612,8 +629,12 @@ + + + + @@ -640,7 +661,6 @@ - @@ -662,7 +682,9 @@ - + + + @@ -678,7 +700,7 @@ - + @@ -691,7 +713,7 @@ - + @@ -760,6 +782,10 @@ + + + + @@ -768,6 +794,8 @@ + + diff --git a/ile_de_france/src/main/resources/corsica/corsica_facilities.xml.gz b/ile_de_france/src/main/resources/corsica/corsica_facilities.xml.gz index fa74a6959..e20bc9c59 100644 Binary files a/ile_de_france/src/main/resources/corsica/corsica_facilities.xml.gz and b/ile_de_france/src/main/resources/corsica/corsica_facilities.xml.gz differ diff --git a/ile_de_france/src/main/resources/corsica/corsica_households.xml.gz b/ile_de_france/src/main/resources/corsica/corsica_households.xml.gz index 99ee49139..0d5e8d12d 100644 Binary files a/ile_de_france/src/main/resources/corsica/corsica_households.xml.gz and b/ile_de_france/src/main/resources/corsica/corsica_households.xml.gz differ diff --git a/ile_de_france/src/main/resources/corsica/corsica_network.xml.gz b/ile_de_france/src/main/resources/corsica/corsica_network.xml.gz index 14b1783fb..a443eeefd 100644 Binary files a/ile_de_france/src/main/resources/corsica/corsica_network.xml.gz and b/ile_de_france/src/main/resources/corsica/corsica_network.xml.gz differ diff --git a/ile_de_france/src/main/resources/corsica/corsica_population.xml.gz b/ile_de_france/src/main/resources/corsica/corsica_population.xml.gz index bb685031e..3db2aefa3 100644 Binary files a/ile_de_france/src/main/resources/corsica/corsica_population.xml.gz and b/ile_de_france/src/main/resources/corsica/corsica_population.xml.gz differ diff --git a/ile_de_france/src/main/resources/corsica/corsica_transit_schedule.xml.gz b/ile_de_france/src/main/resources/corsica/corsica_transit_schedule.xml.gz index 26ce87260..a752cdbb2 100644 Binary files a/ile_de_france/src/main/resources/corsica/corsica_transit_schedule.xml.gz and b/ile_de_france/src/main/resources/corsica/corsica_transit_schedule.xml.gz differ diff --git a/ile_de_france/src/main/resources/corsica/corsica_transit_vehicles.xml.gz b/ile_de_france/src/main/resources/corsica/corsica_transit_vehicles.xml.gz index cf4c22a66..00c3120c4 100644 Binary files a/ile_de_france/src/main/resources/corsica/corsica_transit_vehicles.xml.gz and b/ile_de_france/src/main/resources/corsica/corsica_transit_vehicles.xml.gz differ diff --git a/ile_de_france/src/test/java/org/eqasim/ile_de_france/TestCorisica.java b/ile_de_france/src/test/java/org/eqasim/ile_de_france/TestCorisica.java index 2b66a9854..68ef11258 100644 --- a/ile_de_france/src/test/java/org/eqasim/ile_de_france/TestCorisica.java +++ b/ile_de_france/src/test/java/org/eqasim/ile_de_france/TestCorisica.java @@ -40,7 +40,7 @@ public void tearDown() throws IOException { public void testCorsicaPipeline() throws ConfigurationException, InterruptedException, MalformedURLException, IOException { - Assert.assertEquals(3162, countPersons("corsica_test/corsica_population.xml.gz")); + Assert.assertEquals(389, countPersons("corsica_test/corsica_population.xml.gz")); // Run the simulation { @@ -50,14 +50,14 @@ public void testCorsicaPipeline() "--config:controler.outputDirectory", "corsica_test/simulation_output", // }); - Assert.assertEquals(3162, countPersons("corsica_test/simulation_output/output_plans.xml.gz")); + Assert.assertEquals(389, countPersons("corsica_test/simulation_output/output_plans.xml.gz")); Map counts = countLegs("corsica_test/simulation_output/output_events.xml.gz"); - Assert.assertEquals(7759, (long) counts.get("car")); - Assert.assertEquals(894, (long) counts.get("car_passenger")); - Assert.assertEquals(3699, (long) counts.get("walk")); - Assert.assertEquals(2, (long) counts.get("bike")); - Assert.assertEquals(47, (long) counts.get("pt")); + Assert.assertEquals(994, (long) counts.get("car")); + Assert.assertEquals(129, (long) counts.get("car_passenger")); + Assert.assertEquals(221, (long) counts.get("walk")); + Assert.assertEquals(0, (long) counts.getOrDefault("bike", 0L)); + Assert.assertEquals(5, (long) counts.get("pt")); } // Run the mode choice + following simulation @@ -82,7 +82,7 @@ public void testCorsicaPipeline() "--output-path", "corsica_test", // }); - Assert.assertEquals(1286, countPersons("corsica_test/cut_population.xml.gz")); + Assert.assertEquals(171, countPersons("corsica_test/cut_population.xml.gz")); } // Run the cut simulation @@ -94,18 +94,12 @@ public void testCorsicaPipeline() }); Map counts = countLegs("corsica_test/cut_output/output_events.xml.gz"); - Assert.assertEquals(2991, (long) counts.get("car")); - Assert.assertEquals(387, (long) counts.get("car_passenger")); - // Note that walk has increased from 847 to 7458 when integrating access/egress - // for network-based modes. This is because MATSim really generates an access - // and egress for *every* network-based trip, even if the distance is zero. This - // value is higher than in the baseline (before cutting) case, because in the - // current Corsica scenario, there are no access egress legs in the base version - // (and don't get generated a lot after only two iterations). - Assert.assertEquals(7458, (long) counts.get("walk")); - Assert.assertEquals(0, (long) counts.getOrDefault("bike", 0L)); - Assert.assertEquals(9, (long) counts.get("pt")); - Assert.assertEquals(95, (long) counts.get("outside")); + Assert.assertEquals(423, (long) counts.get("car")); + Assert.assertEquals(53, (long) counts.get("car_passenger")); + Assert.assertEquals(103, (long) counts.get("walk")); + Assert.assertEquals(0, (long) counts.getOrDefault("bike", 0L)); + Assert.assertEquals(0, (long) counts.getOrDefault("pt", 0L)); + Assert.assertEquals(6, (long) counts.get("outside")); } } diff --git a/ile_de_france/src/test/java/org/eqasim/ile_de_france/TestEmissions.java b/ile_de_france/src/test/java/org/eqasim/ile_de_france/TestEmissions.java new file mode 100644 index 000000000..890a7837a --- /dev/null +++ b/ile_de_france/src/test/java/org/eqasim/ile_de_france/TestEmissions.java @@ -0,0 +1,191 @@ +package org.eqasim.ile_de_france; + +import org.apache.commons.io.FileUtils; +import org.eqasim.core.simulation.EqasimConfigurator; +import org.eqasim.core.simulation.analysis.EqasimAnalysisModule; +import org.eqasim.core.simulation.mode_choice.AbstractEqasimExtension; +import org.eqasim.core.simulation.mode_choice.EqasimModeChoiceModule; +import org.eqasim.core.simulation.mode_choice.parameters.ModeParameters; +import org.eqasim.ile_de_france.emissions.RunComputeEmissionsEvents; +import org.eqasim.ile_de_france.emissions.RunExportEmissionsNetwork; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.population.Person; +import org.matsim.core.config.CommandLine; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.config.groups.ControlerConfigGroup; +import org.matsim.core.config.groups.QSimConfigGroup; +import org.matsim.core.controler.Controler; +import org.matsim.core.network.NetworkUtils; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.core.utils.gis.ShapeFileReader; +import org.matsim.examples.ExamplesUtils; +import org.matsim.utils.objectattributes.attributable.Attributes; +import org.matsim.vehicles.*; +import org.opengis.feature.simple.SimpleFeature; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; + +public class TestEmissions { + + @Before + public void setUp() throws IOException { + URL fixtureUrl = getClass().getResource("/melun"); + FileUtils.copyDirectory(new File(fixtureUrl.getPath()), new File("melun_test/input")); + var coldAverageFile = "sample_41_EFA_ColdStart_vehcat_2020average.csv"; + var coldDetailedFile = "sample_41_EFA_ColdStart_SubSegm_2020detailed.csv"; + var hotAverageFile = "sample_41_EFA_HOT_vehcat_2020average.csv"; + var hotDetailedFile = "sample_41_EFA_HOT_SubSegm_2020detailed.csv"; + for (String file: new String[]{ coldAverageFile, coldDetailedFile, hotAverageFile, hotDetailedFile}) { + Files.copy(ExamplesUtils.class.getResourceAsStream("/test/scenarios/emissions-sampleScenario/" + file), + Paths.get("melun_test/input/", file), + REPLACE_EXISTING); + } + } + + @After + public void tearDown() throws IOException { + FileUtils.deleteDirectory(new File("melun_test")); + } + + private void runMelunSimulation() { + EqasimConfigurator eqasimConfigurator = new EqasimConfigurator(); + Config config = ConfigUtils.loadConfig("melun_test/input/config_emissions.xml", eqasimConfigurator.getConfigGroups()); + ((ControlerConfigGroup) config.getModules().get(ControlerConfigGroup.GROUP_NAME)).setOutputDirectory("melun_test/output"); + + Scenario scenario = ScenarioUtils.createScenario(config); + eqasimConfigurator.configureScenario(scenario); + ScenarioUtils.loadScenario(scenario); + eqasimConfigurator.adjustScenario(scenario); + + + Controler controller = new Controler(scenario); + eqasimConfigurator.configureController(controller); + controller.addOverridingModule(new EqasimModeChoiceModule()); + controller.addOverridingModule(new EqasimAnalysisModule()); + controller.addOverridingModule(new AbstractEqasimExtension() { + @Override + protected void installEqasimExtension() { + bind(ModeParameters.class); + bindModeAvailability("DefaultModeAvailability").toProvider(() -> (person, trips) -> { + Set modes = new HashSet<>(); + modes.add(TransportMode.walk); + modes.add(TransportMode.pt); + modes.add(TransportMode.car); + modes.add(TransportMode.bike); + // Add special mode "car_passenger" if applicable + Boolean isCarPassenger = (Boolean) person.getAttributes().getAttribute("isPassenger"); + if(isCarPassenger) { + modes.add("car_passenger"); + } + return modes; + }).asEagerSingleton(); + } + }); + controller.run(); + } + + private void runCreateVehicles() { + VehicleType testCarType = VehicleUtils.createVehicleType(Id.create("test_car", VehicleType.class)); + testCarType.setLength(7.5); + testCarType.setWidth(1.); + testCarType.setNetworkMode("car"); + Attributes hbefa_attributes = testCarType.getEngineInformation().getAttributes(); + hbefa_attributes.putAttribute("HbefaVehicleCategory", "PASSENGER_CAR"); + hbefa_attributes.putAttribute("HbefaTechnology", "diesel"); + hbefa_attributes.putAttribute("HbefaSizeClass", "<1,4L"); + hbefa_attributes.putAttribute("HbefaEmissionsConcept", "PC diesel Euro-3 (DPF)"); + + Vehicles vehicles = VehicleUtils.createVehiclesContainer(); + vehicles.addVehicleType(testCarType); + + EqasimConfigurator eqasimConfigurator = new EqasimConfigurator(); + Config config = ConfigUtils.loadConfig("melun_test/input/config.xml", eqasimConfigurator.getConfigGroups()); + Scenario scenario = ScenarioUtils.loadScenario(config); + for (Person person: scenario.getPopulation().getPersons().values()) { + Vehicle vehicle = VehicleUtils.createVehicle( + Id.createVehicleId(person.getId().toString()), + testCarType); + vehicles.addVehicle(vehicle); + } + + MatsimVehicleWriter writer = new MatsimVehicleWriter(vehicles); + writer.writeFile("melun_test/input/vehicles.xml"); + } + + private void runModifyConfig() { + Config config = ConfigUtils.loadConfig("melun_test/input/config.xml"); + config.controler().setOutputDirectory("melun_test/output"); + config.qsim().setVehiclesSource(QSimConfigGroup.VehiclesSource.fromVehiclesData); + config.vehicles().setVehiclesFile("vehicles.xml"); + ConfigUtils.writeConfig(config, "melun_test/input/config_emissions.xml"); + } + + private void runModifyNetwork() { + Config config = ConfigUtils.loadConfig("melun_test/input/config.xml"); + Scenario scenario = ScenarioUtils.loadScenario(config); + Network network = scenario.getNetwork(); + for (Link link: network.getLinks().values()) { + // this forces the OSM Mapping code to use URB/Local/50 as it the only thing we have in the sample HBEFA. + NetworkUtils.setType(link, "tertiary"); + link.getAttributes().putAttribute(NetworkUtils.ALLOWED_SPEED, 50 / 3.6); + } + NetworkUtils.writeNetwork(network, "melun_test/input/network.xml.gz"); + } + + private void runMelunEmissions() throws CommandLine.ConfigurationException { + RunComputeEmissionsEvents.main(new String[] { + "--config-path", "melun_test/input/config_emissions.xml", + "--hbefa-cold-avg", "sample_41_EFA_ColdStart_vehcat_2020average.csv", + "--hbefa-hot-avg", "sample_41_EFA_HOT_vehcat_2020average.csv", + "--hbefa-cold-detailed", "sample_41_EFA_ColdStart_SubSegm_2020detailed.csv", + "--hbefa-hot-detailed", "sample_41_EFA_HOT_SubSegm_2020detailed.csv", + }); + + RunExportEmissionsNetwork.main(new String[] { + "--config-path", "melun_test/input/config_emissions.xml", + "--pollutants", "PM,CO,NOx,Unknown", + "--time-bin-size", "3600" + }); + + Collection features = ShapeFileReader.getAllFeatures("melun_test/output/emissions_network.shp"); + assert features.size() == 32999; + SimpleFeature feature = features.stream().filter(f -> + f.getAttribute("link").toString().equals("163994") + & f.getAttribute("time").toString().equals("43200") + ).findFirst().orElse(null); + assert feature != null; + assert feature.getAttribute("PM").equals(0.006847378350421); + assert feature.getAttribute("CO").equals(0.456258730331835); + assert feature.getAttribute("NOx").equals(0.477558671071797); + assert feature.getAttribute("Unknown").equals(Double.NaN); + + // TODO : test RunComputeEmissionsGrid + } + + @Test + public void runTestEmissions() throws CommandLine.ConfigurationException { + runCreateVehicles(); + runModifyConfig(); + runModifyNetwork(); + runMelunSimulation(); + runMelunEmissions(); + } + +} diff --git a/pom.xml b/pom.xml index a830cd978..1ce7a14b4 100644 --- a/pom.xml +++ b/pom.xml @@ -20,9 +20,9 @@ - 11 - 11 - 14.0 + 17 + 17 + 15.0 @@ -106,6 +106,12 @@ ${matsim.version} + + org.matsim + matsim-examples + ${matsim.version} + + junit junit diff --git a/vdf/src/main/java/org/eqasim/vdf/VDFUpdateListener.java b/vdf/src/main/java/org/eqasim/vdf/VDFUpdateListener.java index 49e4c1e8a..c07f65201 100644 --- a/vdf/src/main/java/org/eqasim/vdf/VDFUpdateListener.java +++ b/vdf/src/main/java/org/eqasim/vdf/VDFUpdateListener.java @@ -5,7 +5,8 @@ import java.net.URL; import java.util.List; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eqasim.vdf.analysis.FlowWriter; import org.eqasim.vdf.handlers.VDFTrafficHandler; import org.eqasim.vdf.travel_time.VDFTravelTime; @@ -23,7 +24,7 @@ import com.google.common.io.Files; public class VDFUpdateListener implements IterationEndsListener, StartupListener, ShutdownListener { - private final static Logger logger = Logger.getLogger(VDFUpdateListener.class); + private final static Logger logger = LogManager.getLogger(VDFUpdateListener.class); private final String VDF_FILE = "vdf.bin"; private final String FLOW_FILE = "vdf_flow.csv"; diff --git a/vdf/src/main/java/org/eqasim/vdf/handlers/VDFHorizonHandler.java b/vdf/src/main/java/org/eqasim/vdf/handlers/VDFHorizonHandler.java index 57c5fe381..7d7075f74 100644 --- a/vdf/src/main/java/org/eqasim/vdf/handlers/VDFHorizonHandler.java +++ b/vdf/src/main/java/org/eqasim/vdf/handlers/VDFHorizonHandler.java @@ -13,7 +13,8 @@ import java.util.List; import java.util.Map; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eqasim.vdf.VDFScope; import org.eqasim.vdf.io.VDFReaderInterface; import org.eqasim.vdf.io.VDFWriterInterface; @@ -37,7 +38,7 @@ public class VDFHorizonHandler implements VDFTrafficHandler, LinkEnterEventHandl private final IdMap> counts = new IdMap<>(Link.class); private final List>> state = new LinkedList<>(); - private final static Logger logger = Logger.getLogger(VDFHorizonHandler.class); + private final static Logger logger = LogManager.getLogger(VDFHorizonHandler.class); public VDFHorizonHandler(Network network, VDFScope scope, int horizon, int numberOfThreads) { this.scope = scope; diff --git a/vdf/src/main/java/org/eqasim/vdf/travel_time/VDFTravelTime.java b/vdf/src/main/java/org/eqasim/vdf/travel_time/VDFTravelTime.java index f129967ac..485925ec8 100644 --- a/vdf/src/main/java/org/eqasim/vdf/travel_time/VDFTravelTime.java +++ b/vdf/src/main/java/org/eqasim/vdf/travel_time/VDFTravelTime.java @@ -5,7 +5,8 @@ import java.util.List; import java.util.Map; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.eqasim.vdf.VDFScope; import org.eqasim.vdf.travel_time.function.VolumeDelayFunction; import org.matsim.api.core.v01.Id; @@ -29,7 +30,7 @@ public class VDFTravelTime implements TravelTime { private final IdMap> travelTimes = new IdMap<>(Link.class); - private final Logger logger = Logger.getLogger(VDFTravelTime.class); + private final Logger logger = LogManager.getLogger(VDFTravelTime.class); public VDFTravelTime(VDFScope scope, double minimumSpeed, double capacityFacotor, double samplingRate, Network network, VolumeDelayFunction vdf, double crossingPenalty) {