-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Emission noise analysis #9
Changes from all commits
c7b48d7
3986b35
fff091d
d5834ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* *********************************************************************** * | ||
* project: org.matsim.* | ||
* Controler.java | ||
* * | ||
* *********************************************************************** * | ||
* * | ||
* copyright : (C) 2007 by the members listed in the COPYING, * | ||
* LICENSE and WARRANTY file. * | ||
* email : info at matsim dot org * | ||
* * | ||
* *********************************************************************** * | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* See also COPYING, LICENSE and WARRANTY file * | ||
* * | ||
* *********************************************************************** */ | ||
|
||
package org.matsim.dashboards; | ||
|
||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.matsim.application.ApplicationUtils; | ||
import org.matsim.application.MATSimAppCommand; | ||
import org.matsim.application.options.ShpOptions; | ||
import org.matsim.core.config.Config; | ||
import org.matsim.core.config.ConfigUtils; | ||
import org.matsim.simwrapper.Dashboard; | ||
import org.matsim.simwrapper.SimWrapper; | ||
import org.matsim.simwrapper.SimWrapperConfigGroup; | ||
import org.matsim.simwrapper.dashboard.NoiseDashboard; | ||
import picocli.CommandLine; | ||
|
||
import java.io.IOException; | ||
import java.io.InterruptedIOException; | ||
import java.nio.file.Path; | ||
import java.util.List; | ||
|
||
@CommandLine.Command( | ||
name = "simwrapper", | ||
description = "Run additional analysis and create SimWrapper dashboard for existing run output." | ||
) | ||
final class LausitzSimWrapperRunner implements MATSimAppCommand { | ||
|
||
private static final Logger log = LogManager.getLogger(LausitzSimWrapperRunner.class); | ||
|
||
@CommandLine.Parameters(arity = "1..*", description = "Path to run output directories for which dashboards are to be generated.") | ||
private List<Path> inputPaths; | ||
|
||
@CommandLine.Mixin | ||
private final ShpOptions shp = new ShpOptions(); | ||
|
||
@CommandLine.Option(names = "--noise", defaultValue = "false", description = "create noise dashboard") | ||
private boolean noise; | ||
|
||
|
||
private LausitzSimWrapperRunner(){ | ||
} | ||
|
||
@Override | ||
public Integer call() throws Exception { | ||
|
||
if (!noise){ | ||
throw new IllegalArgumentException("you have not configured any dashboard to be created! Please use command line parameters!"); | ||
} | ||
|
||
for (Path runDirectory : inputPaths) { | ||
log.info("Running on {}", runDirectory); | ||
|
||
Path configPath = ApplicationUtils.matchInput("config.xml", runDirectory); | ||
Config config = ConfigUtils.loadConfig(configPath.toString()); | ||
SimWrapper sw = SimWrapper.create(config); | ||
|
||
SimWrapperConfigGroup simwrapperCfg = ConfigUtils.addOrGetModule(config, SimWrapperConfigGroup.class); | ||
if (shp.isDefined()){ | ||
simwrapperCfg.defaultParams().shp = shp.getShapeFile(); | ||
} | ||
//skip default dashboards | ||
simwrapperCfg.defaultDashboards = SimWrapperConfigGroup.Mode.disabled; | ||
|
||
//add dashboards according to command line parameters | ||
// TODO: if more dashboards are to be added here, we need to check if noise==true before adding noise dashboard here | ||
sw.addDashboard(Dashboard.customize(new NoiseDashboard()).context("noise")); | ||
|
||
|
||
try { | ||
sw.generate(runDirectory, true); | ||
sw.run(runDirectory); | ||
} catch (IOException e) { | ||
throw new InterruptedIOException(); | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
public static void main(String[] args) { | ||
new LausitzSimWrapperRunner().execute(args); | ||
|
||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,10 @@ | |
import org.matsim.application.prepare.network.CreateNetworkFromSumo; | ||
import org.matsim.application.prepare.population.*; | ||
import org.matsim.application.prepare.pt.CreateTransitScheduleFromGtfs; | ||
import org.matsim.contrib.emissions.HbefaRoadTypeMapping; | ||
import org.matsim.contrib.emissions.HbefaVehicleCategory; | ||
import org.matsim.contrib.emissions.OsmHbefaMapping; | ||
import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; | ||
import org.matsim.contrib.vsp.scenario.SnzActivities; | ||
import org.matsim.core.config.Config; | ||
import org.matsim.core.config.ConfigUtils; | ||
|
@@ -25,6 +29,7 @@ | |
import org.matsim.core.config.groups.ScoringConfigGroup; | ||
import org.matsim.core.controler.AbstractModule; | ||
import org.matsim.core.controler.Controler; | ||
import org.matsim.core.network.NetworkUtils; | ||
import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule; | ||
import org.matsim.core.router.costcalculators.TravelDisutilityFactory; | ||
import org.matsim.core.router.util.TravelTime; | ||
|
@@ -33,6 +38,9 @@ | |
import org.matsim.run.prepare.PreparePopulation; | ||
import org.matsim.simwrapper.SimWrapperConfigGroup; | ||
import org.matsim.simwrapper.SimWrapperModule; | ||
import org.matsim.vehicles.EngineInformation; | ||
import org.matsim.vehicles.VehicleType; | ||
import org.matsim.vehicles.VehicleUtils; | ||
import picocli.CommandLine; | ||
import playground.vsp.pt.fare.DistanceBasedPtFareParams; | ||
import playground.vsp.pt.fare.PtFareConfigGroup; | ||
|
@@ -60,10 +68,21 @@ public class LausitzScenario extends MATSimApplication { | |
|
||
public static final String VERSION = "1.1"; | ||
private static final String FREIGHT = "freight"; | ||
private static final String AVERAGE = "average"; | ||
|
||
// To decrypt hbefa input files set MATSIM_DECRYPTION_PASSWORD as environment variable. ask VSP for access. | ||
private static final String HBEFA_2020_PATH = "https://svn.vsp.tu-berlin.de/repos/public-svn/3507bb3997e5657ab9da76dbedbb13c9b5991d3e/0e73947443d68f95202b71a156b337f7f71604ae/"; | ||
private static final String HBEFA_FILE_COLD_DETAILED = HBEFA_2020_PATH + "82t7b02rc0rji2kmsahfwp933u2rfjlkhfpi2u9r20.enc"; | ||
private static final String HBEFA_FILE_WARM_DETAILED = HBEFA_2020_PATH + "944637571c833ddcf1d0dfcccb59838509f397e6.enc"; | ||
private static final String HBEFA_FILE_COLD_AVERAGE = HBEFA_2020_PATH + "r9230ru2n209r30u2fn0c9rn20n2rujkhkjhoewt84202.enc" ; | ||
private static final String HBEFA_FILE_WARM_AVERAGE = HBEFA_2020_PATH + "7eff8f308633df1b8ac4d06d05180dd0c5fdf577.enc"; | ||
|
||
@CommandLine.Mixin | ||
private final SampleOptions sample = new SampleOptions( 100, 25, 10, 1); | ||
|
||
@CommandLine.Option(names = "--emissions", defaultValue = "PERFORM_EMISSIONS_ANALYSIS", description = "Define if emission analysis should be performed or not.") | ||
private EmissionAnalysisHandling emissions; | ||
|
||
|
||
public LausitzScenario(@Nullable Config config) { | ||
super(config); | ||
|
@@ -124,7 +143,7 @@ protected Config prepareConfig(Config config) { | |
config.routing().setAccessEgressType(RoutingConfigGroup.AccessEgressType.accessEgressModeToLink); | ||
|
||
prepareCommercialTrafficConfig(config); | ||
// TODO: Config options | ||
|
||
// set pt fare calc model to fareZoneBased = fare of vvo tarifzone 20 is paid for trips within fare zone | ||
// every other trip: Deutschlandtarif | ||
// for more info see FareZoneBasedPtFareHandler class in vsp contrib | ||
|
@@ -138,8 +157,17 @@ protected Config prepareConfig(Config config) { | |
throw new RuntimeException(e); | ||
} | ||
|
||
// TODO: recreate counts format with car and trucks | ||
|
||
if (emissions == EmissionAnalysisHandling.PERFORM_EMISSIONS_ANALYSIS) { | ||
// set hbefa input files for emission analysis | ||
EmissionsConfigGroup eConfig = ConfigUtils.addOrGetModule(config, EmissionsConfigGroup.class); | ||
eConfig.setDetailedColdEmissionFactorsFile(HBEFA_FILE_COLD_DETAILED); | ||
eConfig.setDetailedWarmEmissionFactorsFile(HBEFA_FILE_WARM_DETAILED); | ||
eConfig.setAverageColdEmissionFactorsFile(HBEFA_FILE_COLD_AVERAGE); | ||
eConfig.setAverageWarmEmissionFactorsFile(HBEFA_FILE_WARM_AVERAGE); | ||
eConfig.setHbefaTableConsistencyCheckingLevel(EmissionsConfigGroup.HbefaTableConsistencyCheckingLevel.consistent); | ||
eConfig.setDetailedVsAverageLookupBehavior(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If only running AVERAGE vehicle types, the LookupBehaviour could be set IMO to directlyAverage (or whatever its name is). Together with just setting the average tables, it makes a bit more clear, that you run an average analysis (which is totally fine!) |
||
} | ||
return config; | ||
} | ||
|
||
|
@@ -158,6 +186,22 @@ protected void prepareScenario(Scenario scenario) { | |
link.setAllowedModes(newModes); | ||
} | ||
} | ||
|
||
if (emissions == EmissionAnalysisHandling.PERFORM_EMISSIONS_ANALYSIS) { | ||
// do not use VspHbefaRoadTypeMapping() as it results in almost every road to mapped to "highway"! | ||
HbefaRoadTypeMapping roadTypeMapping = OsmHbefaMapping.build(); | ||
// the type attribute in our network has the prefix "highway" for all links but pt links. | ||
// we need to delete that because OsmHbefaMapping does not handle that. | ||
for (Link link : scenario.getNetwork().getLinks().values()) { | ||
//pt links can be disregarded | ||
if (!link.getAllowedModes().contains("pt")) { | ||
NetworkUtils.setType(link, NetworkUtils.getType(link).replaceFirst("highway.", "")); | ||
} | ||
} | ||
roadTypeMapping.addHbefaMappings(scenario.getNetwork()); | ||
Comment on lines
+189
to
+201
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As also written directly to Simon: We at VSP should have our current scenarios in a state, that the HBEFA attributes are part of the input network. This is a network property and thus should not depend on the mapping in the analysis script itself. |
||
|
||
prepareVehicleTypesForEmissionAnalysis(scenario); | ||
} | ||
} | ||
|
||
@Override | ||
|
@@ -225,4 +269,54 @@ public static void prepareCommercialTrafficConfig(Config config) { | |
); | ||
} | ||
} | ||
|
||
private static void prepareVehicleTypesForEmissionAnalysis(Scenario scenario) { | ||
for (VehicleType type : scenario.getVehicles().getVehicleTypes().values()) { | ||
EngineInformation engineInformation = type.getEngineInformation(); | ||
|
||
// only set engine information if none are present | ||
if (engineInformation.getAttributes().isEmpty()) { | ||
switch (type.getId().toString()) { | ||
case TransportMode.car -> { | ||
VehicleUtils.setHbefaVehicleCategory(engineInformation, HbefaVehicleCategory.PASSENGER_CAR.toString()); | ||
VehicleUtils.setHbefaTechnology(engineInformation, AVERAGE); | ||
VehicleUtils.setHbefaSizeClass(engineInformation, AVERAGE); | ||
VehicleUtils.setHbefaEmissionsConcept(engineInformation, AVERAGE); | ||
} | ||
case TransportMode.ride -> { | ||
// ignore ride, the mode routed on network, but then teleported | ||
VehicleUtils.setHbefaVehicleCategory(engineInformation, HbefaVehicleCategory.NON_HBEFA_VEHICLE.toString()); | ||
VehicleUtils.setHbefaTechnology(engineInformation, AVERAGE); | ||
VehicleUtils.setHbefaSizeClass(engineInformation, AVERAGE); | ||
VehicleUtils.setHbefaEmissionsConcept(engineInformation, AVERAGE); | ||
} | ||
case FREIGHT -> { | ||
VehicleUtils.setHbefaVehicleCategory(engineInformation, HbefaVehicleCategory.HEAVY_GOODS_VEHICLE.toString()); | ||
VehicleUtils.setHbefaTechnology(engineInformation, AVERAGE); | ||
VehicleUtils.setHbefaSizeClass(engineInformation, AVERAGE); | ||
VehicleUtils.setHbefaEmissionsConcept(engineInformation, AVERAGE); | ||
} | ||
case TransportMode.bike -> { | ||
// ignore bikes | ||
VehicleUtils.setHbefaVehicleCategory(engineInformation, HbefaVehicleCategory.NON_HBEFA_VEHICLE.toString()); | ||
VehicleUtils.setHbefaTechnology(engineInformation, AVERAGE); | ||
VehicleUtils.setHbefaSizeClass(engineInformation, AVERAGE); | ||
VehicleUtils.setHbefaEmissionsConcept(engineInformation, AVERAGE); | ||
} | ||
default -> throw new IllegalArgumentException("does not know how to handle vehicleType " + type.getId().toString()); | ||
} | ||
} | ||
} | ||
|
||
// ignore all pt veh types | ||
scenario.getTransitVehicles() | ||
.getVehicleTypes() | ||
.values().forEach(type -> VehicleUtils.setHbefaVehicleCategory(type.getEngineInformation(), HbefaVehicleCategory.NON_HBEFA_VEHICLE.toString())); | ||
Comment on lines
+274
to
+314
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit the same as for the links... should be IMO part of the input. Since this script here only sets average values, if no value is set, I do not know if the input has the engineInformation set correctly or not. Maybe also make a bit more clear that you set here everything to average. |
||
} | ||
|
||
/** | ||
* Defines if all necessary configs for emissions analysis should be made | ||
* and hence if emissions analysis is performed or not (will fail without configs). | ||
*/ | ||
enum EmissionAnalysisHandling {PERFORM_EMISSIONS_ANALYSIS, DO_NOT_PERFORM_EMISSIONS_ANALYSIS} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you only use AVERAGE, you should be able to run it without the detailed tables.