diff --git a/core/src/main/java/org/eqasim/core/components/config/ConfigAdapter.java b/core/src/main/java/org/eqasim/core/components/config/ConfigAdapter.java index ef5cf520f..3c4c58fab 100644 --- a/core/src/main/java/org/eqasim/core/components/config/ConfigAdapter.java +++ b/core/src/main/java/org/eqasim/core/components/config/ConfigAdapter.java @@ -14,8 +14,8 @@ static public void run(String[] args, EqasimConfigurator configurator, ConfigAda .requireOptions("input-path", "output-path", "prefix") // .build(); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("input-path"), configurator.getConfigGroups()); - configurator.addOptionalConfigGroups(config); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("input-path")); + configurator.updateConfig(config); adapter.accept(config, cmd.getOptionStrict("prefix")); new ConfigWriter(config).write(cmd.getOptionStrict("output-path")); diff --git a/core/src/main/java/org/eqasim/core/components/emissions/RunComputeEmissionsEvents.java b/core/src/main/java/org/eqasim/core/components/emissions/RunComputeEmissionsEvents.java index 6b99a07d1..a3aa06fdf 100644 --- a/core/src/main/java/org/eqasim/core/components/emissions/RunComputeEmissionsEvents.java +++ b/core/src/main/java/org/eqasim/core/components/emissions/RunComputeEmissionsEvents.java @@ -1,6 +1,5 @@ package org.eqasim.core.components.emissions; -import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.eqasim.core.misc.ClassUtils; import org.eqasim.core.simulation.EqasimConfigurator; @@ -13,7 +12,6 @@ import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.config.CommandLine; import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.Injector; @@ -39,9 +37,9 @@ public static void main(String[] args) throws CommandLine.ConfigurationException configurator = new EqasimConfigurator(); } - ConfigGroup[] configGroups = ArrayUtils.addAll(configurator.getConfigGroups(), new EmissionsConfigGroup()); - - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configGroups); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.registerConfigGroup(new EmissionsConfigGroup(), false); + configurator.updateConfig(config); cmd.applyConfiguration(config); EmissionsConfigGroup emissionsConfig = (EmissionsConfigGroup) config.getModules().get("emissions"); diff --git a/core/src/main/java/org/eqasim/core/components/emissions/RunComputeEmissionsGrid.java b/core/src/main/java/org/eqasim/core/components/emissions/RunComputeEmissionsGrid.java index 985339266..5f20f67ee 100644 --- a/core/src/main/java/org/eqasim/core/components/emissions/RunComputeEmissionsGrid.java +++ b/core/src/main/java/org/eqasim/core/components/emissions/RunComputeEmissionsGrid.java @@ -1,16 +1,13 @@ package org.eqasim.core.components.emissions; -import org.apache.commons.lang3.ArrayUtils; import org.eqasim.core.misc.ClassUtils; import org.eqasim.core.simulation.EqasimConfigurator; import org.geotools.api.feature.simple.SimpleFeature; import org.locationtech.jts.geom.Geometry; import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.emissions.analysis.EmissionGridAnalyzer; -import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; import org.matsim.core.config.CommandLine; import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; import org.matsim.core.network.NetworkUtils; import org.matsim.core.network.io.MatsimNetworkReader; @@ -32,9 +29,8 @@ public static void main(String[] args) throws CommandLine.ConfigurationException configurator = new EqasimConfigurator(); } - ConfigGroup[] configGroups = ArrayUtils.addAll(configurator.getConfigGroups(), new EmissionsConfigGroup()); - - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configGroups); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); cmd.applyConfiguration(config); final String outputDirectory = config.controller().getOutputDirectory() + "/"; diff --git a/core/src/main/java/org/eqasim/core/components/emissions/RunExportEmissionsNetwork.java b/core/src/main/java/org/eqasim/core/components/emissions/RunExportEmissionsNetwork.java index 5440ce735..d6404b7fe 100644 --- a/core/src/main/java/org/eqasim/core/components/emissions/RunExportEmissionsNetwork.java +++ b/core/src/main/java/org/eqasim/core/components/emissions/RunExportEmissionsNetwork.java @@ -6,7 +6,6 @@ import java.util.List; import java.util.Map; -import org.apache.commons.lang3.ArrayUtils; import org.eqasim.core.misc.ClassUtils; import org.eqasim.core.simulation.EqasimConfigurator; import org.geotools.api.feature.simple.SimpleFeature; @@ -19,11 +18,9 @@ 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; import org.matsim.core.config.CommandLine; import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; import org.matsim.core.events.EventsUtils; import org.matsim.core.network.NetworkUtils; @@ -49,9 +46,8 @@ public static void main(String[] args) throws CommandLine.ConfigurationException configurator = new EqasimConfigurator(); } - ConfigGroup[] configGroups = ArrayUtils.addAll(configurator.getConfigGroups(), new EmissionsConfigGroup()); - - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configGroups); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); cmd.applyConfiguration(config); final String outputDirectory = config.controller().getOutputDirectory() + "/"; diff --git a/core/src/main/java/org/eqasim/core/scenario/config/RunGenerateConfig.java b/core/src/main/java/org/eqasim/core/scenario/config/RunGenerateConfig.java index 5aa683c8e..0498cad13 100644 --- a/core/src/main/java/org/eqasim/core/scenario/config/RunGenerateConfig.java +++ b/core/src/main/java/org/eqasim/core/scenario/config/RunGenerateConfig.java @@ -15,7 +15,8 @@ static public void main(String[] args) throws ConfigurationException { .build(); EqasimConfigurator configurator = new EqasimConfigurator(); - Config config = ConfigUtils.createConfig(configurator.getConfigGroups()); + Config config = ConfigUtils.createConfig(); + configurator.updateConfig(config); String prefix = cmd.getOptionStrict("prefix"); double sampleSize = Double.parseDouble(cmd.getOptionStrict("sample-size")); diff --git a/core/src/main/java/org/eqasim/core/scenario/cutter/RunScenarioCutter.java b/core/src/main/java/org/eqasim/core/scenario/cutter/RunScenarioCutter.java index 4dcdf1db9..2eb56bf16 100644 --- a/core/src/main/java/org/eqasim/core/scenario/cutter/RunScenarioCutter.java +++ b/core/src/main/java/org/eqasim/core/scenario/cutter/RunScenarioCutter.java @@ -31,7 +31,7 @@ import org.eqasim.core.scenario.validation.VehiclesValidator; import org.eqasim.core.simulation.EqasimConfigurator; import org.eqasim.core.simulation.mode_choice.AbstractEqasimExtension; -import org.eqasim.core.simulation.termination.EqasimTerminationModule; +import org.eqasim.core.simulation.termination.EqasimTerminationConfigGroup; import org.matsim.api.core.v01.Scenario; import org.matsim.contribs.discrete_mode_choice.modules.DiscreteModeChoiceModule; import org.matsim.core.config.CommandLine; @@ -71,9 +71,9 @@ static public void main(String[] args) throws ConfigurationException, IOExceptio // Load scenario EqasimConfigurator configurator = new EqasimConfigurator(); - configurator.getModules().removeIf(m -> m instanceof EqasimTerminationModule); - - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); + config.removeModule(EqasimTerminationConfigGroup.GROUP_NAME); cmd.applyConfiguration(config); VehiclesValidator.validate(config); @@ -111,7 +111,7 @@ static public void main(String[] args) throws ConfigurationException, IOExceptio // Cut population Injector populationCutterInjector = new InjectorBuilder(scenario) // - .addOverridingModules(configurator.getModules().stream() + .addOverridingModules(configurator.getModules(config).stream() .filter(module -> !(module instanceof AbstractEqasimExtension) && !(module instanceof DiscreteModeChoiceModule)).toList()) // .addOverridingModule( new PopulationCutterModule(extent, numberOfThreads, 40, cmd.getOption("events-path"))) // @@ -162,14 +162,15 @@ static public void main(String[] args) throws ConfigurationException, IOExceptio // "Cut" config // (we need to reload it, because it has become locked at this point) - config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configurator.getConfigGroups()); + config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); cmd.applyConfiguration(config); ConfigCutter configCutter = new ConfigCutter(prefix); configCutter.run(config); // Final routing Injector routingInjector = new InjectorBuilder(scenario) // - .addOverridingModules(configurator.getModules().stream() + .addOverridingModules(configurator.getModules(config).stream() .filter(module -> !(module instanceof AbstractEqasimExtension) && !(module instanceof DiscreteModeChoiceModule)).toList()) // .addOverridingModule(new PopulationRouterModule(numberOfThreads, 100, false)) // .addOverridingModule(new CutterTravelTimeModule(travelTime)) // diff --git a/core/src/main/java/org/eqasim/core/scenario/cutter/RunScenarioCutterV2.java b/core/src/main/java/org/eqasim/core/scenario/cutter/RunScenarioCutterV2.java index 521e62659..45a2a4685 100644 --- a/core/src/main/java/org/eqasim/core/scenario/cutter/RunScenarioCutterV2.java +++ b/core/src/main/java/org/eqasim/core/scenario/cutter/RunScenarioCutterV2.java @@ -44,9 +44,9 @@ static public void main(String[] args) String outputPath = cmd.getOptionStrict("output-path"); EqasimConfigurator eqasimConfigurator = new EqasimConfigurator(); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), eqasimConfigurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + eqasimConfigurator.updateConfig(config); cmd.applyConfiguration(config); - eqasimConfigurator.addOptionalConfigGroups(config); if(!config.getModules().containsKey(VDFConfigGroup.GROUP_NAME) || !config.getModules().containsKey(VDFEngineConfigGroup.GROUP_NAME)) { throw new IllegalStateException(String.format("This scenario cutter only works with configs where both '%s' and '%s' modules are used", VDFConfigGroup.GROUP_NAME, VDFEngineConfigGroup.GROUP_NAME)); @@ -126,9 +126,9 @@ static public void main(String[] args) // "Cut" config // (we need to reload it, because it has become locked at this point) - config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), eqasimConfigurator.getConfigGroups()); + config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + eqasimConfigurator.updateConfig(config); cmd.applyConfiguration(config); - eqasimConfigurator.addOptionalConfigGroups(config); ConfigCutter configCutter = new ConfigCutter(prefix); configCutter.run(config); diff --git a/core/src/main/java/org/eqasim/core/scenario/routing/RunPopulationRouting.java b/core/src/main/java/org/eqasim/core/scenario/routing/RunPopulationRouting.java index 03fbcd54f..543e54783 100644 --- a/core/src/main/java/org/eqasim/core/scenario/routing/RunPopulationRouting.java +++ b/core/src/main/java/org/eqasim/core/scenario/routing/RunPopulationRouting.java @@ -29,9 +29,9 @@ static public void main(String[] args) throws ConfigurationException, Interrupte .build(); EqasimConfigurator configurator = new EqasimConfigurator(); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); config.getModules().remove(EqasimTerminationConfigGroup.GROUP_NAME); - configurator.addOptionalConfigGroups(config); cmd.applyConfiguration(config); config.replanning().clearStrategySettings(); VehiclesValidator.validate(config); @@ -59,7 +59,7 @@ static public void main(String[] args) throws ConfigurationException, Interrupte } Injector injector = new InjectorBuilder(scenario) // - .addOverridingModules(configurator.getModules().stream() + .addOverridingModules(configurator.getModules(config).stream() .filter(module -> !(module instanceof AbstractEqasimExtension)) // .filter(module -> !(module instanceof DiscreteModeChoiceModule)).toList()) // .addOverridingModule(new PopulationRouterModule(numberOfThreads, batchSize, true, modes)) // diff --git a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java index 7c101031a..4d6e700ec 100644 --- a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java +++ b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java @@ -1,6 +1,8 @@ package org.eqasim.core.simulation; -import java.util.*; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; import java.util.function.BiConsumer; import org.eqasim.core.components.EqasimComponentsModule; @@ -17,15 +19,15 @@ import org.eqasim.core.simulation.modes.feeder_drt.MultiModeFeederDrtModule; import org.eqasim.core.simulation.modes.feeder_drt.config.MultiModeFeederDrtConfigGroup; import org.eqasim.core.simulation.modes.feeder_drt.mode_choice.EqasimFeederDrtModeChoiceModule; -import org.eqasim.core.simulation.modes.transit_with_abstract_access.TransitWithAbstractAccessModule; import org.eqasim.core.simulation.modes.transit_with_abstract_access.TransitWithAbstractAbstractAccessModuleConfigGroup; +import org.eqasim.core.simulation.modes.transit_with_abstract_access.TransitWithAbstractAccessModule; import org.eqasim.core.simulation.modes.transit_with_abstract_access.TransitWithAbstractAccessQSimModule; import org.eqasim.core.simulation.modes.transit_with_abstract_access.mode_choice.TransitWithAbstractAccessModeChoiceModule; import org.eqasim.core.simulation.modes.transit_with_abstract_access.routing.AbstractAccessRouteFactory; import org.eqasim.core.simulation.modes.transit_with_abstract_access.routing.DefaultAbstractAccessRoute; import org.eqasim.core.simulation.termination.EqasimTerminationConfigGroup; import org.eqasim.core.simulation.termination.EqasimTerminationModule; -import org.eqasim.core.simulation.termination.mode_share.ModeShareModule; +import org.eqasim.core.simulation.termination.mode_share.TerminationModeShareModule; import org.eqasim.core.simulation.vdf.VDFConfigGroup; import org.eqasim.core.simulation.vdf.VDFModule; import org.eqasim.core.simulation.vdf.VDFQSimModule; @@ -41,7 +43,7 @@ import org.matsim.contrib.dvrp.run.DvrpConfigGroup; import org.matsim.contrib.dvrp.run.DvrpModule; import org.matsim.contrib.dvrp.run.DvrpQSimComponents; -import org.matsim.contrib.dvrp.run.MultiModal; +import org.matsim.contrib.emissions.utils.EmissionsConfigGroup; import org.matsim.contribs.discrete_mode_choice.modules.DiscreteModeChoiceModule; import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup; import org.matsim.core.config.Config; @@ -56,151 +58,218 @@ import ch.sbb.matsim.routing.pt.raptor.SwissRailRaptorModule; public class EqasimConfigurator { - protected final List configGroups = new LinkedList<>(); - protected final List modules = new LinkedList<>(); - protected final List qsimModules = new LinkedList<>(); - private final Map> optionalModules = new HashMap<>(); - private final Map> optionalQSimModules = new HashMap<>(); - private final Map>> optionalQSimComponentConfigurationSteps = new HashMap<>(); - private final Map optionalConfigGroups = new HashMap<>(); - - public EqasimConfigurator() { - configGroups.addAll(Arrays.asList( // - new SwissRailRaptorConfigGroup(), // - new EqasimConfigGroup(), // - new DiscreteModeChoiceConfigGroup(), // - new EqasimRaptorConfigGroup() // - )); - - modules.addAll(Arrays.asList( // - new SwissRailRaptorModule(), // - new EqasimTransitModule(), // - new DiscreteModeChoiceModule(), // - new EqasimComponentsModule(), // - new EpsilonModule(), // - new EqasimRaptorModule(), - new EqasimModeChoiceModule()// - )); - - qsimModules.addAll(Arrays.asList( // - new EqasimTransitQSimModule(), // - new EqasimTrafficQSimModule() // - )); - - this.registerOptionalConfigGroup(new MultiModeDrtConfigGroup(), - Collections.singleton(new MultiModeDrtModule()), - Collections.emptyList(), - Collections.singletonList((controller, components) -> - DvrpQSimComponents.activateAllModes((MultiModal) controller.getConfig().getModules().get(MultiModeDrtConfigGroup.GROUP_NAME)).configure(components))); - - this.registerOptionalConfigGroup(new DvrpConfigGroup(), Collections.singleton(new DvrpModule())); - this.registerOptionalConfigGroup(new EqasimTerminationConfigGroup(), List.of(new EqasimTerminationModule(), new ModeShareModule())); - this.registerOptionalConfigGroup(new MultiModeFeederDrtConfigGroup(), List.of(new MultiModeFeederDrtModule(), new EqasimFeederDrtModeChoiceModule())); - this.registerOptionalConfigGroup( - new TransitWithAbstractAbstractAccessModuleConfigGroup(), - List.of(new TransitWithAbstractAccessModule(), - new TransitWithAbstractAccessModeChoiceModule()), - List.of(new TransitWithAbstractAccessQSimModule()), - Collections.singletonList((controller, components) -> TransitWithAbstractAccessQSimModule.configure(components, controller.getConfig()))); - this.registerOptionalConfigGroup(new VDFConfigGroup(), - List.of(new VDFModule()), - List.of(new VDFQSimModule())); - this.registerOptionalConfigGroup(new VDFEngineConfigGroup(), - List.of(new VDFEngineModule()), - Collections.emptyList(), - Collections.singletonList((controller, components) -> components.addNamedComponent(VDFEngineModule.COMPONENT_NAME))); - this.registerOptionalConfigGroup(new LegTimeConstraintConfigGroup(), Collections.singleton(new LegTimeConstraintModule())); - } - - public ConfigGroup[] getConfigGroups() { - return configGroups.toArray(ConfigGroup[]::new); - } - - public List getModules() { - return modules; - } - - public List getQSimModules() { - return qsimModules; - } - - public void configureController(Controler controller) { - Map modules = controller.getConfig().getModules(); - - this.optionalModules.keySet().stream() - .filter(modules::containsKey) - .map(this.optionalModules::get) - .flatMap(Collection::stream) - .forEach(controller::addOverridingModule); - - this.getModules().forEach(controller::addOverridingModule); - - this.optionalQSimModules.keySet().stream() - .filter(modules::containsKey) - .map(this.optionalQSimModules::get) - .flatMap(Collection::stream) - .forEach(controller::addOverridingQSimModule); - this.getQSimModules().forEach(controller::addOverridingQSimModule); - - controller.configureQSimComponents(components -> { - optionalQSimComponentConfigurationSteps.entrySet().stream() - .filter(e -> controller.getConfig().getModules().containsKey(e.getKey())) - .map(Map.Entry::getValue) - .flatMap(Collection::stream) - .forEach(step -> step.accept(controller, components)); - EqasimTransitQSimModule.configure(components, controller.getConfig()); - }); - } - - protected void registerOptionalConfigGroup(ConfigGroup configGroup) { - registerOptionalConfigGroup(configGroup, new ArrayList<>()); - } - - protected void registerOptionalConfigGroup(ConfigGroup configGroup, Collection modules) { - registerOptionalConfigGroup(configGroup, modules, new ArrayList<>()); - } - - protected void registerOptionalConfigGroup(ConfigGroup configGroup, Collection modules, Collection qsimModules) { - registerOptionalConfigGroup(configGroup, modules, qsimModules, new ArrayList<>()); - } - protected void registerOptionalConfigGroup(ConfigGroup configGroup, Collection modules, Collection qsimModules, List> componentsConsumers) { - this.optionalConfigGroups.put(configGroup.getName(), configGroup); - this.optionalModules.computeIfAbsent(configGroup.getName(), key -> new ArrayList<>()).addAll(modules); - this.optionalQSimModules.computeIfAbsent(configGroup.getName(), key -> new ArrayList<>()).addAll(qsimModules); - this.optionalQSimComponentConfigurationSteps.computeIfAbsent(configGroup.getName(), key -> new ArrayList<>()).addAll(componentsConsumers); - } - - public void addOptionalConfigGroups(Config config) { - for (ConfigGroup configGroup : optionalConfigGroups.values()) { - ConfigGroup existingConfigGroup = config.getModules().get(configGroup.getName()); - // if a config group with the same name exist and is still a generic ConfigGroup instance, we replace it by the optional config group instance - if (existingConfigGroup != null && existingConfigGroup.getClass().equals(ConfigGroup.class)) { - config.addModule(configGroup); - } - } - } - - public void configureScenario(Scenario scenario) { - scenario.getPopulation().getFactory().getRouteFactories().setRouteFactory(DrtRoute.class, new DrtRouteFactory()); - scenario.getPopulation().getFactory().getRouteFactories().setRouteFactory(DefaultAbstractAccessRoute.class, new AbstractAccessRouteFactory()); - } - - public void adjustScenario(Scenario scenario) { - for (Household household : scenario.getHouseholds().getHouseholds().values()) { - for (Id memberId : household.getMemberIds()) { - Person person = scenario.getPopulation().getPersons().get(memberId); - - if (person != null) { - copyAttribute(household, person, "bikeAvailability"); - copyAttribute(household, person, "spRegion"); - } - } - } - } - - static protected void copyAttribute(Household household, Person person, String attribute) { - if (household.getAttributes().getAsMap().containsKey(attribute)) { - person.getAttributes().putAttribute(attribute, household.getAttributes().getAttribute(attribute)); - } - } + public EqasimConfigurator() { + // Standard eqasim configuration + registerConfigGroup(new SwissRailRaptorConfigGroup(), false); + registerConfigGroup(new EqasimConfigGroup(), false); + registerConfigGroup(new DiscreteModeChoiceConfigGroup(), false); + registerConfigGroup(new EqasimRaptorConfigGroup(), false); + + registerModule(new SwissRailRaptorModule()); + registerModule(new EqasimTransitModule()); + registerModule(new DiscreteModeChoiceModule()); + registerModule(new EqasimComponentsModule()); + registerModule(new EpsilonModule()); + registerModule(new EqasimRaptorModule()); + registerModule(new EqasimModeChoiceModule()); + + registerQSimModule(new EqasimTransitQSimModule()); + registerQSimModule(new EqasimTrafficQSimModule()); + + registerComponents(EqasimTransitQSimModule::configure); + + // Termination + registerConfigGroup(new EqasimTerminationConfigGroup(), false); + registerModule(new EqasimTerminationModule(), EqasimTerminationConfigGroup.GROUP_NAME); + registerModule(new TerminationModeShareModule(), EqasimTerminationConfigGroup.GROUP_NAME); + + // DRT functionality + registerConfigGroup(new DvrpConfigGroup(), true); + registerConfigGroup(new MultiModeDrtConfigGroup(), true); + + registerModule(new DvrpModule(), DvrpConfigGroup.GROUP_NAME); + registerModule(new MultiModeDrtModule(), MultiModeDrtConfigGroup.GROUP_NAME); + + registerComponents((components, config) -> { + MultiModeDrtConfigGroup configGroup = MultiModeDrtConfigGroup.get(config); + DvrpQSimComponents.activateAllModes(configGroup).configure(components); + }, MultiModeDrtConfigGroup.GROUP_NAME); + + // Feeder functionality + registerConfigGroup(new MultiModeFeederDrtConfigGroup(), true); + + registerModule(new MultiModeFeederDrtModule(), MultiModeFeederDrtConfigGroup.GROUP_NAME); + registerModule(new EqasimFeederDrtModeChoiceModule(), MultiModeFeederDrtConfigGroup.GROUP_NAME); + + // Abstract access + registerConfigGroup(new TransitWithAbstractAbstractAccessModuleConfigGroup(), true); + + registerModule(new TransitWithAbstractAccessModule(), + TransitWithAbstractAbstractAccessModuleConfigGroup.GROUP_NAME); + registerModule(new TransitWithAbstractAccessModeChoiceModule(), + TransitWithAbstractAbstractAccessModuleConfigGroup.GROUP_NAME); + + registerQSimModule(new TransitWithAbstractAccessQSimModule(), + TransitWithAbstractAbstractAccessModuleConfigGroup.GROUP_NAME); + + registerComponents(TransitWithAbstractAccessQSimModule::configure, + TransitWithAbstractAbstractAccessModuleConfigGroup.GROUP_NAME); + + // VDF functionality + registerConfigGroup(new VDFConfigGroup(), true); + registerModule(new VDFModule(), VDFConfigGroup.GROUP_NAME); + registerQSimModule(new VDFQSimModule(), VDFConfigGroup.GROUP_NAME); + + registerConfigGroup(new VDFEngineConfigGroup(), true); + registerModule(new VDFEngineModule(), VDFEngineConfigGroup.GROUP_NAME); + registerComponents((components, config) -> { + VDFEngineModule.configureQSim(components); + }, VDFEngineConfigGroup.GROUP_NAME); + + // Leg time constraint functionality + registerConfigGroup(new LegTimeConstraintConfigGroup(), true); + registerModule(new LegTimeConstraintModule(), LegTimeConstraintConfigGroup.GROUP_NAME); + + // Emissions + registerConfigGroup(new EmissionsConfigGroup(), true); + } + + private record ConfigGroupItem(ConfigGroup configGroup, boolean isOptional) { + } + + private record ModuleItem(AbstractModule module, String configName) { + } + + private record QSimModuleItem(AbstractQSimModule module, String configName) { + } + + private record ComponentsItem(BiConsumer configurator, String configName) { + } + + private final List configGroups = new LinkedList<>(); + private final List modules = new LinkedList<>(); + private final List qsimModules = new LinkedList<>(); + private final List components = new LinkedList<>(); + + public void registerConfigGroup(ConfigGroup configGroup, boolean isOptional) { + configGroups.add(new ConfigGroupItem(configGroup, isOptional)); + } + + public void registerModule(AbstractModule module) { + registerModule(module, null); + } + + public void registerModule(AbstractModule module, String configName) { + modules.add(new ModuleItem(module, configName)); + } + + public void registerQSimModule(AbstractQSimModule module) { + registerQSimModule(module, null); + } + + public void registerQSimModule(AbstractQSimModule module, String configName) { + qsimModules.add(new QSimModuleItem(module, configName)); + } + + public void registerComponents(BiConsumer comoonent) { + registerComponents(comoonent, null); + } + + public void registerComponents(BiConsumer comoonent, String configName) { + components.add(new ComponentsItem(comoonent, configName)); + } + + public void updateConfig(Config config) { + for (ConfigGroupItem item : configGroups) { + ConfigGroup existing = config.getModules().get(item.configGroup.getName()); + + if (!item.isOptional || existing != null) { + if (existing == null) { + config.addModule(item.configGroup); + } else if (existing.getClass().equals(item.configGroup.getClass())) { + // fine, already properly initialized + } else if (existing.getClass().equals(ConfigGroup.class)) { + // not initialized yet, will be transformed + config.addModule(item.configGroup); + } else { + throw new IllegalStateException("Config group with this name already existing in a different type: " + + item.configGroup.getName()); + } + } + } + } + + public List getModules(Config config) { + List active = new LinkedList<>(); + + for (ModuleItem item : modules) { + if (item.configName == null || config.getModules().containsKey(item.configName)) { + active.add(item.module); + } + } + + return Collections.unmodifiableList(active); + } + + public List getQSimModules(Config config) { + List active = new LinkedList<>(); + + for (QSimModuleItem item : qsimModules) { + if (item.configName == null || config.getModules().containsKey(item.configName)) { + active.add(item.module); + } + } + + return Collections.unmodifiableList(active); + } + + public void configureComponents(QSimComponentsConfig components, Config config) { + for (ComponentsItem item : this.components) { + if (item.configName == null || config.getModules().containsKey(item.configName)) { + item.configurator.accept(components, config); + } + } + } + + public void configureController(Controler controller) { + Config config = controller.getConfig(); + + for (AbstractModule module : getModules(config)) { + controller.addOverridingModule(module); + } + + for (AbstractQSimModule qsimModule : getQSimModules(config)) { + controller.addOverridingQSimModule(qsimModule); + } + + controller.configureQSimComponents(components -> { + configureComponents(components, config); + }); + } + + public void configureScenario(Scenario scenario) { + scenario.getPopulation().getFactory().getRouteFactories().setRouteFactory(DrtRoute.class, + new DrtRouteFactory()); + scenario.getPopulation().getFactory().getRouteFactories().setRouteFactory(DefaultAbstractAccessRoute.class, + new AbstractAccessRouteFactory()); + } + + public void adjustScenario(Scenario scenario) { + for (Household household : scenario.getHouseholds().getHouseholds().values()) { + for (Id memberId : household.getMemberIds()) { + Person person = scenario.getPopulation().getPersons().get(memberId); + + if (person != null) { + copyAttribute(household, person, "bikeAvailability"); + copyAttribute(household, person, "spRegion"); + } + } + } + } + + static protected void copyAttribute(Household household, Person person, String attribute) { + if (household.getAttributes().getAsMap().containsKey(attribute)) { + person.getAttributes().putAttribute(attribute, household.getAttributes().getAttribute(attribute)); + } + } } 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 45f680412..eb4b3d747 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 @@ -2,7 +2,14 @@ import java.net.MalformedURLException; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.DoubleSummaryStatistics; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.DoubleStream; import java.util.stream.IntStream; @@ -200,8 +207,9 @@ public static void main(String[] args) throws CommandLine.ConfigurationException configurator = new EqasimConfigurator(); } - Config config = ConfigUtils.loadConfig(inputConfigPath, configurator.getConfigGroups()); - + Config config = ConfigUtils.loadConfig(inputConfigPath); + configurator.updateConfig(config); + adapt(config, info.get("vehicles-paths"), info.get("operational-schemes"), info.get("estimators"), info.get("cost-models"), info.get("add-leg-time-constraint"), qsimEndtime, cmd.getOption("mode-availability").orElse(null)); cmd.applyConfiguration(config); diff --git a/core/src/main/java/org/eqasim/core/simulation/modes/feeder_drt/analysis/run/RunFeederDrtPassengerAnalysis.java b/core/src/main/java/org/eqasim/core/simulation/modes/feeder_drt/analysis/run/RunFeederDrtPassengerAnalysis.java index d45de5340..2ffdfd72a 100644 --- a/core/src/main/java/org/eqasim/core/simulation/modes/feeder_drt/analysis/run/RunFeederDrtPassengerAnalysis.java +++ b/core/src/main/java/org/eqasim/core/simulation/modes/feeder_drt/analysis/run/RunFeederDrtPassengerAnalysis.java @@ -1,5 +1,9 @@ package org.eqasim.core.simulation.modes.feeder_drt.analysis.run; +import java.io.File; +import java.io.IOException; +import java.util.Map; + import org.eqasim.core.simulation.EqasimConfigurator; import org.eqasim.core.simulation.modes.drt.analysis.utils.VehicleRegistry; import org.eqasim.core.simulation.modes.feeder_drt.analysis.passengers.FeederTripSequenceListener; @@ -16,10 +20,6 @@ import org.matsim.core.network.NetworkUtils; import org.matsim.core.network.io.MatsimNetworkReader; -import java.io.File; -import java.io.IOException; -import java.util.Map; - public class RunFeederDrtPassengerAnalysis { @@ -53,8 +53,8 @@ static public void main(String[] args) throws CommandLine.ConfigurationException String outputPath = cmd.getOptionStrict("output-path"); EqasimConfigurator configurator = new EqasimConfigurator(); - Config config = ConfigUtils.loadConfig(configPath, configurator.getConfigGroups()); - configurator.addOptionalConfigGroups(config); + Config config = ConfigUtils.loadConfig(configPath); + configurator.updateConfig(config); Network network = NetworkUtils.createNetwork(); new MatsimNetworkReader(network).readFile(networkPath); diff --git a/core/src/main/java/org/eqasim/core/simulation/modes/feeder_drt/utils/AdaptConfigForFeederDrt.java b/core/src/main/java/org/eqasim/core/simulation/modes/feeder_drt/utils/AdaptConfigForFeederDrt.java index f86b5e5ac..193235254 100644 --- a/core/src/main/java/org/eqasim/core/simulation/modes/feeder_drt/utils/AdaptConfigForFeederDrt.java +++ b/core/src/main/java/org/eqasim/core/simulation/modes/feeder_drt/utils/AdaptConfigForFeederDrt.java @@ -162,8 +162,8 @@ public static void main(String[] args) throws CommandLine.ConfigurationException configurator = new EqasimConfigurator(); } - Config config = ConfigUtils.loadConfig(inputConfigPath, configurator.getConfigGroups()); - configurator.addOptionalConfigGroups(config); + Config config = ConfigUtils.loadConfig(inputConfigPath); + configurator.updateConfig(config); adapt(config, info.get("base-pt-modes"), info.get("base-drt-modes"), info.get("estimators"), info.get("access-egress-transit-stop-modes"), info.get("access-egress-transit-stop-ids"), cmd.getOption("mode-availability").orElse(null)); diff --git a/core/src/main/java/org/eqasim/core/simulation/termination/mode_share/ModeShareModule.java b/core/src/main/java/org/eqasim/core/simulation/termination/mode_share/TerminationModeShareModule.java similarity index 95% rename from core/src/main/java/org/eqasim/core/simulation/termination/mode_share/ModeShareModule.java rename to core/src/main/java/org/eqasim/core/simulation/termination/mode_share/TerminationModeShareModule.java index 5dd75b596..febbd111d 100644 --- a/core/src/main/java/org/eqasim/core/simulation/termination/mode_share/ModeShareModule.java +++ b/core/src/main/java/org/eqasim/core/simulation/termination/mode_share/TerminationModeShareModule.java @@ -7,7 +7,7 @@ import com.google.inject.Provides; import com.google.inject.Singleton; -public class ModeShareModule extends AbstractModule { +public class TerminationModeShareModule extends AbstractModule { @Override public void install() { EqasimTerminationConfigGroup terminationConfig = EqasimTerminationConfigGroup.getOrCreate(getConfig()); diff --git a/core/src/main/java/org/eqasim/core/simulation/vdf/VDFModule.java b/core/src/main/java/org/eqasim/core/simulation/vdf/VDFModule.java index 53ba1918d..027976f45 100644 --- a/core/src/main/java/org/eqasim/core/simulation/vdf/VDFModule.java +++ b/core/src/main/java/org/eqasim/core/simulation/vdf/VDFModule.java @@ -8,6 +8,7 @@ import org.eqasim.core.components.config.EqasimConfigGroup; import org.eqasim.core.scenario.cutter.extent.ScenarioExtent; import org.eqasim.core.scenario.cutter.extent.ShapeScenarioExtent; +import org.eqasim.core.simulation.mode_choice.AbstractEqasimExtension; import org.eqasim.core.simulation.vdf.handlers.VDFHorizonHandler; import org.eqasim.core.simulation.vdf.handlers.VDFInterpolationHandler; import org.eqasim.core.simulation.vdf.handlers.VDFTrafficHandler; @@ -17,15 +18,14 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.groups.QSimConfigGroup; -import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.OutputDirectoryHierarchy; import com.google.inject.Provides; import com.google.inject.Singleton; -public class VDFModule extends AbstractModule { +public class VDFModule extends AbstractEqasimExtension { @Override - public void install() { + protected void installEqasimExtension() { VDFConfigGroup vdfConfig = VDFConfigGroup.getOrCreate(getConfig()); for (String mode : vdfConfig.getModes()) { @@ -70,7 +70,10 @@ public VDFScope provideVDFScope(VDFConfigGroup config) { @Singleton public VDFTravelTime provideVDFTravelTime(VDFConfigGroup config, VDFScope scope, Network network, VolumeDelayFunction vdf, QSimConfigGroup qsimConfig, EqasimConfigGroup eqasimConfig) throws IOException { - ScenarioExtent updateExtent = config.getUpdateAreaShapefile() == null ? null : new ShapeScenarioExtent.Builder(new File(ConfigGroup.getInputFileURL(getConfig().getContext(), config.getUpdateAreaShapefile()).getPath()), Optional.empty(), Optional.empty()).build(); + ScenarioExtent updateExtent = config.getUpdateAreaShapefile() == null ? null + : new ShapeScenarioExtent.Builder(new File(ConfigGroup + .getInputFileURL(getConfig().getContext(), config.getUpdateAreaShapefile()).getPath()), + Optional.empty(), Optional.empty()).build(); return new VDFTravelTime(scope, config.getMinimumSpeed(), config.getCapacityFactor(), eqasimConfig.getSampleSize(), network, vdf, eqasimConfig.getCrossingPenalty(), updateExtent); } diff --git a/core/src/main/java/org/eqasim/core/simulation/vdf/engine/VDFEngineModule.java b/core/src/main/java/org/eqasim/core/simulation/vdf/engine/VDFEngineModule.java index 0cb88864d..7d266eeb6 100644 --- a/core/src/main/java/org/eqasim/core/simulation/vdf/engine/VDFEngineModule.java +++ b/core/src/main/java/org/eqasim/core/simulation/vdf/engine/VDFEngineModule.java @@ -1,20 +1,21 @@ package org.eqasim.core.simulation.vdf.engine; +import org.eqasim.core.simulation.mode_choice.AbstractEqasimExtension; import org.eqasim.core.simulation.vdf.handlers.VDFTrafficHandler; import org.eqasim.core.simulation.vdf.travel_time.VDFTravelTime; import org.matsim.api.core.v01.network.Network; -import org.matsim.core.controler.AbstractModule; import org.matsim.core.mobsim.qsim.AbstractQSimModule; +import org.matsim.core.mobsim.qsim.components.QSimComponentsConfig; import com.google.common.base.Verify; import com.google.inject.Provides; import com.google.inject.Singleton; -public class VDFEngineModule extends AbstractModule { +public class VDFEngineModule extends AbstractEqasimExtension { public static final String COMPONENT_NAME = "VDFEngine"; @Override - public void install() { + public void installEqasimExtension() { VDFEngineConfigGroup engineConfig = VDFEngineConfigGroup.getOrCreate(getConfig()); for (String mode : engineConfig.getModes()) { @@ -36,4 +37,8 @@ public VDFEngine provideVDFEngine(VDFTravelTime travelTime, Network network, VDF } }); } + + static public void configureQSim(QSimComponentsConfig components) { + components.addNamedComponent(COMPONENT_NAME); + } } diff --git a/core/src/main/java/org/eqasim/core/simulation/vdf/utils/AdaptConfigForVDF.java b/core/src/main/java/org/eqasim/core/simulation/vdf/utils/AdaptConfigForVDF.java index 34309b957..dfb0ea555 100644 --- a/core/src/main/java/org/eqasim/core/simulation/vdf/utils/AdaptConfigForVDF.java +++ b/core/src/main/java/org/eqasim/core/simulation/vdf/utils/AdaptConfigForVDF.java @@ -54,7 +54,8 @@ public static void main(String[] args) throws CommandLine.ConfigurationException boolean engine = Boolean.parseBoolean(commandLine.getOption("engine").orElse("false")); EqasimConfigurator eqasimConfigurator = new EqasimConfigurator(); - Config config = ConfigUtils.loadConfig(inputPath, eqasimConfigurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig(inputPath); + eqasimConfigurator.updateConfig(config); adaptConfigForVDF(config, engine); commandLine.applyConfiguration(config); ConfigUtils.writeConfig(config, outputPath); diff --git a/core/src/main/java/org/eqasim/core/standalone_mode_choice/RunStandaloneModeChoice.java b/core/src/main/java/org/eqasim/core/standalone_mode_choice/RunStandaloneModeChoice.java index c17078130..3ee954ed9 100644 --- a/core/src/main/java/org/eqasim/core/standalone_mode_choice/RunStandaloneModeChoice.java +++ b/core/src/main/java/org/eqasim/core/standalone_mode_choice/RunStandaloneModeChoice.java @@ -44,7 +44,6 @@ import org.matsim.api.core.v01.population.Population; import org.matsim.core.config.CommandLine; import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigGroup; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.OutputDirectoryHierarchy; @@ -162,17 +161,10 @@ public static void main(String[] args) throws CommandLine.ConfigurationException // Loading the config EqasimConfigurator configurator = cmd.hasOption(EQASIM_CONFIGURATOR_CLASS) ? ClassUtils.getInstanceOfClassExtendingOtherClass(cmd.getOptionStrict(EQASIM_CONFIGURATOR_CLASS), EqasimConfigurator.class) : new EqasimConfigurator(); - ConfigGroup[] configGroups = new ConfigGroup[configurator.getConfigGroups().length+1]; - int i=0; - for(ConfigGroup configGroup: configurator.getConfigGroups()) { - configGroups[i] = configGroup; - i++; - } - // We should add this module now so that parameters can be overridden by the commandline - configGroups[i] = new StandaloneModeChoiceConfigGroup(); + configurator.registerConfigGroup(new StandaloneModeChoiceConfigGroup(), false); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict(CMD_CONFIG_PATH), configGroups); - configurator.addOptionalConfigGroups(config); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict(CMD_CONFIG_PATH)); + configurator.updateConfig(config); cmd.applyConfiguration(config); VehiclesValidator.validate(config); diff --git a/core/src/main/java/org/eqasim/core/standalone_mode_choice/StandaloneModeChoiceConfigurator.java b/core/src/main/java/org/eqasim/core/standalone_mode_choice/StandaloneModeChoiceConfigurator.java index 71dda0049..bb23527d6 100644 --- a/core/src/main/java/org/eqasim/core/standalone_mode_choice/StandaloneModeChoiceConfigurator.java +++ b/core/src/main/java/org/eqasim/core/standalone_mode_choice/StandaloneModeChoiceConfigurator.java @@ -56,7 +56,7 @@ protected void registerOptionalModule(String moduleName, AbstractModule module) public final List getModeChoiceModules(Config config) { List modules = new ArrayList<>(); - new EqasimConfigurator().getModules().stream().filter(module -> !(module instanceof EqasimTerminationModule)).forEach(modules::add); + new EqasimConfigurator().getModules(config).stream().filter(module -> !(module instanceof EqasimTerminationModule)).forEach(modules::add); modules.add(new TimeInterpretationModule()); modules.add(new StandaloneModeChoiceModule(getConfig())); // We add a module that just binds the PersonAnalysisFilter without having to add the whole EqasimAnalysisModule diff --git a/core/src/main/java/org/eqasim/core/tools/RunImputeHeadway.java b/core/src/main/java/org/eqasim/core/tools/RunImputeHeadway.java index 996432b9a..2ceb3cc3b 100644 --- a/core/src/main/java/org/eqasim/core/tools/RunImputeHeadway.java +++ b/core/src/main/java/org/eqasim/core/tools/RunImputeHeadway.java @@ -22,7 +22,8 @@ static public void main(String[] args) throws ConfigurationException, Interrupte .build(); EqasimConfigurator configurator = new EqasimConfigurator(); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); cmd.applyConfiguration(config); config.replanning().clearStrategySettings(); @@ -35,7 +36,7 @@ static public void main(String[] args) throws ConfigurationException, Interrupte ScenarioUtils.loadScenario(scenario); Injector injector = new InjectorBuilder(scenario) // - .addOverridingModules(configurator.getModules()) // + .addOverridingModules(configurator.getModules(config)) // .addOverridingModule(new HeadwayImputerModule(numberOfThreads, batchSize, true, interval)) // .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 aaf60a027..3348a3578 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 @@ -66,7 +66,8 @@ static public void main(String[] args) throws ConfigurationException, JsonGenera .build(); EqasimConfigurator configurator = new EqasimConfigurator(); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); cmd.applyConfiguration(config); // No opportunity scoring @@ -262,7 +263,7 @@ static public void main(String[] args) throws ConfigurationException, JsonGenera Optional outputConfigPath = cmd.getOption("output-config-path"); Injector injector = new InjectorBuilder(scenario) // - .addOverridingModules(configurator.getModules()) // + .addOverridingModules(configurator.getModules(config)) // .addOverridingModule(new HeadwayImputerModule(numberOfThreads, batchSize, false, interval)).build(); Provider routerProvider = injector.getProvider(TransitRouter.class); diff --git a/core/src/main/java/org/eqasim/core/tools/routing/RunBatchRoadRouter.java b/core/src/main/java/org/eqasim/core/tools/routing/RunBatchRoadRouter.java index ce38ba146..b3536688a 100644 --- a/core/src/main/java/org/eqasim/core/tools/routing/RunBatchRoadRouter.java +++ b/core/src/main/java/org/eqasim/core/tools/routing/RunBatchRoadRouter.java @@ -47,7 +47,8 @@ static public void main(String[] args) throws ConfigurationException, JsonGenera .build(); EqasimConfigurator configurator = new EqasimConfigurator(); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); cmd.applyConfiguration(config); Scenario scenario = ScenarioUtils.createScenario(config); @@ -66,7 +67,7 @@ static public void main(String[] args) throws ConfigurationException, JsonGenera } Injector injector = new InjectorBuilder(scenario) // - .addOverridingModules(configurator.getModules()) // + .addOverridingModules(configurator.getModules(config)) // .addOverridingModule(new AbstractModule() { @Override public void install() { diff --git a/core/src/test/java/org/eqasim/TestEmissions.java b/core/src/test/java/org/eqasim/TestEmissions.java index bef761534..1c4c14073 100644 --- a/core/src/test/java/org/eqasim/TestEmissions.java +++ b/core/src/test/java/org/eqasim/TestEmissions.java @@ -1,16 +1,5 @@ package org.eqasim; -import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; - -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; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -38,23 +27,21 @@ 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.geotools.api.feature.simple.SimpleFeature; import org.junit.After; import org.junit.Assert; 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.events.handler.PersonDepartureEventHandler; 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.api.experimental.events.EventsManager; import org.matsim.core.config.CommandLine; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.groups.ControllerConfigGroup; -import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.controler.Controler; import org.matsim.core.events.EventsUtils; import org.matsim.core.events.MatsimEventsReader; @@ -65,11 +52,9 @@ import org.matsim.utils.objectattributes.attributable.Attributes; import org.matsim.vehicles.MatsimVehicleReader; import org.matsim.vehicles.MatsimVehicleWriter; -import org.matsim.vehicles.Vehicle; import org.matsim.vehicles.VehicleType; import org.matsim.vehicles.VehicleUtils; import org.matsim.vehicles.Vehicles; -import org.geotools.api.feature.simple.SimpleFeature; public class TestEmissions { @@ -94,8 +79,8 @@ public void tearDown() throws IOException { private void runMelunSimulation() { EqasimConfigurator eqasimConfigurator = new EqasimConfigurator(); - Config config = ConfigUtils.loadConfig("melun_test/input/config.xml", - eqasimConfigurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig("melun_test/input/config.xml"); + eqasimConfigurator.updateConfig(config); ((ControllerConfigGroup) config.getModules().get(ControllerConfigGroup.GROUP_NAME)) .setOutputDirectory("melun_test/output"); diff --git a/core/src/test/java/org/eqasim/TestSimulationPipeline.java b/core/src/test/java/org/eqasim/TestSimulationPipeline.java index 26e843fc0..472ca926b 100644 --- a/core/src/test/java/org/eqasim/TestSimulationPipeline.java +++ b/core/src/test/java/org/eqasim/TestSimulationPipeline.java @@ -82,7 +82,8 @@ private void runMelunSimulation(String configPath, String outputPath) { private void runMelunSimulation(String configPath, String outputPath, String inputPlansFile, Integer lastIteration) { EqasimConfigurator eqasimConfigurator = new EqasimConfigurator(); - Config config = ConfigUtils.loadConfig(configPath, eqasimConfigurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig(configPath); + eqasimConfigurator.updateConfig(config); ((ControllerConfigGroup) config.getModules().get(ControllerConfigGroup.GROUP_NAME)).setOutputDirectory(outputPath); if(inputPlansFile != null) { config.plans().setInputFile(inputPlansFile); @@ -91,7 +92,6 @@ private void runMelunSimulation(String configPath, String outputPath, String inp config.controller().setLastIteration(lastIteration); } EqasimConfigGroup.get(config).setTravelTimeRecordingInterval(1000); - eqasimConfigurator.addOptionalConfigGroups(config); Scenario scenario = ScenarioUtils.createScenario(config); eqasimConfigurator.configureScenario(scenario); 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 fd80f894e..b17d6977c 100644 --- a/core/src/test/java/org/eqasim/mode_choice/TestSpecialModeChoiceCases.java +++ b/core/src/test/java/org/eqasim/mode_choice/TestSpecialModeChoiceCases.java @@ -23,6 +23,7 @@ import org.eqasim.core.simulation.EqasimConfigurator; import org.eqasim.core.simulation.mode_choice.EqasimModeChoiceModule; import org.eqasim.core.simulation.mode_choice.parameters.ModeParameters; +import org.eqasim.core.simulation.termination.EqasimTerminationConfigGroup; import org.eqasim.core.simulation.termination.EqasimTerminationModule; import org.junit.After; import org.junit.Test; @@ -158,6 +159,7 @@ static private Set findChains(List trips, int sa new GenerateConfig(cmd, "", 1.0, 1, 1).run(config); config.addModule(new EqasimRaptorConfigGroup()); + config.removeModule(EqasimTerminationConfigGroup.GROUP_NAME); // Make sure the two relevant options (walk vs. bike) both get zero utility DiscreteModeChoiceConfigGroup.getOrCreate(config).setModeAvailability("static"); @@ -166,7 +168,6 @@ static private Set findChains(List trips, int sa // Now create the model EqasimConfigurator configurator = new EqasimConfigurator(); - configurator.getModules().removeIf(m -> m instanceof EqasimTerminationModule); Scenario scenario = ScenarioUtils.createScenario(config); @@ -178,7 +179,7 @@ static private Set findChains(List trips, int sa scenario.getNetwork().addLink(link); Injector injector = new InjectorBuilder(scenario) // - .addOverridingModules(configurator.getModules()) // + .addOverridingModules(configurator.getModules(config)) // .addOverridingModule(new EqasimModeChoiceModule()) // .addOverridingModule(new StaticModeAvailabilityModule()) // .addOverridingModule(new TimeInterpretationModule()) // 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 f8cbf32e4..a8a88cc10 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 @@ -56,7 +56,8 @@ static public void main(String[] args) throws ConfigurationException { URL configUrl = Resources.getResource("corsica/corsica_config.xml"); IDFConfigurator configurator = new IDFConfigurator(); - Config config = ConfigUtils.loadConfig(configUrl, configurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig(configUrl); + configurator.updateConfig(config); config.controller().setLastIteration(2); config.qsim().setFlowCapFactor(1e9); diff --git a/examples/src/main/java/org/eqasim/examples/corsica_vdf/RunCorsicaVDFEngineSimulation.java b/examples/src/main/java/org/eqasim/examples/corsica_vdf/RunCorsicaVDFEngineSimulation.java index 205586350..aa48c8419 100644 --- a/examples/src/main/java/org/eqasim/examples/corsica_vdf/RunCorsicaVDFEngineSimulation.java +++ b/examples/src/main/java/org/eqasim/examples/corsica_vdf/RunCorsicaVDFEngineSimulation.java @@ -4,13 +4,12 @@ import java.util.HashSet; import java.util.Set; -import org.eqasim.core.components.traffic.EqasimTrafficQSimModule; import org.eqasim.core.simulation.analysis.EqasimAnalysisModule; import org.eqasim.core.simulation.mode_choice.EqasimModeChoiceModule; -import org.eqasim.ile_de_france.IDFConfigurator; -import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; import org.eqasim.core.simulation.vdf.VDFConfigGroup; import org.eqasim.core.simulation.vdf.engine.VDFEngineConfigGroup; +import org.eqasim.ile_de_france.IDFConfigurator; +import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; import org.matsim.api.core.v01.Scenario; import org.matsim.core.config.CommandLine; import org.matsim.core.config.CommandLine.ConfigurationException; @@ -32,10 +31,10 @@ static public void main(String[] args) throws ConfigurationException { .build(); IDFConfigurator configurator = new IDFConfigurator(); - configurator.getQSimModules().removeIf(m -> m instanceof EqasimTrafficQSimModule); URL configUrl = Resources.getResource("corsica/corsica_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, configurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig(configUrl); + configurator.updateConfig(config); config.controller().setLastIteration(2); diff --git a/examples/src/main/java/org/eqasim/examples/corsica_vdf/RunCorsicaVDFSimulation.java b/examples/src/main/java/org/eqasim/examples/corsica_vdf/RunCorsicaVDFSimulation.java index f7b53f6f3..dadf66e8e 100644 --- a/examples/src/main/java/org/eqasim/examples/corsica_vdf/RunCorsicaVDFSimulation.java +++ b/examples/src/main/java/org/eqasim/examples/corsica_vdf/RunCorsicaVDFSimulation.java @@ -2,12 +2,11 @@ import java.net.URL; -import org.eqasim.core.components.traffic.EqasimTrafficQSimModule; import org.eqasim.core.simulation.analysis.EqasimAnalysisModule; import org.eqasim.core.simulation.mode_choice.EqasimModeChoiceModule; +import org.eqasim.core.simulation.vdf.VDFConfigGroup; import org.eqasim.ile_de_france.IDFConfigurator; import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; -import org.eqasim.core.simulation.vdf.VDFConfigGroup; import org.matsim.api.core.v01.Scenario; import org.matsim.core.config.CommandLine; import org.matsim.core.config.CommandLine.ConfigurationException; @@ -29,10 +28,10 @@ static public void main(String[] args) throws ConfigurationException { .build(); IDFConfigurator configurator = new IDFConfigurator(); - configurator.getQSimModules().removeIf(m -> m instanceof EqasimTrafficQSimModule); URL configUrl = Resources.getResource("corsica/corsica_config.xml"); - Config config = ConfigUtils.loadConfig(configUrl, configurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig(configUrl); + configurator.updateConfig(config); config.controller().setLastIteration(2); diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java index 4a5ce91bd..5ea5614c7 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java @@ -20,8 +20,8 @@ static public void main(String[] args) throws ConfigurationException { .build(); IDFConfigurator configurator = new IDFConfigurator(); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configurator.getConfigGroups()); - configurator.addOptionalConfigGroups(config); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); cmd.applyConfiguration(config); VehiclesValidator.validate(config); 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 3423fa884..eb1565583 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 @@ -42,7 +42,8 @@ public void tearDown() throws IOException { private void adjustConfig() { IDFConfigurator configurator = new IDFConfigurator(); - Config config = ConfigUtils.loadConfig("corsica_test/corsica_config.xml", configurator.getConfigGroups()); + Config config = ConfigUtils.loadConfig("corsica_test/corsica_config.xml"); + configurator.updateConfig(config); config.vehicles().setVehiclesFile("corsica_vehicles.xml.gz"); config.qsim().setVehiclesSource(VehiclesSource.fromVehiclesData); new ConfigWriter(config).write("corsica_test/corsica_config.xml"); diff --git a/los_angeles/src/main/java/org/eqasim/los_angeles/RunSimulation.java b/los_angeles/src/main/java/org/eqasim/los_angeles/RunSimulation.java index 75be3666d..204cf0386 100644 --- a/los_angeles/src/main/java/org/eqasim/los_angeles/RunSimulation.java +++ b/los_angeles/src/main/java/org/eqasim/los_angeles/RunSimulation.java @@ -22,8 +22,8 @@ static public void main(String[] args) throws ConfigurationException { .build(); EqasimConfigurator configurator = new EqasimConfigurator(); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configurator.getConfigGroups()); - configurator.addOptionalConfigGroups(config); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); EqasimConfigGroup.get(config).setAnalysisInterval(5); EqasimConfigGroup.get(config).setDistanceUnit(DistanceUnit.foot); cmd.applyConfiguration(config); diff --git a/san_francisco/src/main/java/org/eqasim/san_francisco/RunSimulation.java b/san_francisco/src/main/java/org/eqasim/san_francisco/RunSimulation.java index 17cdbe384..45c89b236 100644 --- a/san_francisco/src/main/java/org/eqasim/san_francisco/RunSimulation.java +++ b/san_francisco/src/main/java/org/eqasim/san_francisco/RunSimulation.java @@ -22,8 +22,8 @@ static public void main(String[] args) throws ConfigurationException { .build(); EqasimConfigurator configurator = new EqasimConfigurator(); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configurator.getConfigGroups()); - configurator.addOptionalConfigGroups(config); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); EqasimConfigGroup.get(config).setAnalysisInterval(5); EqasimConfigGroup.get(config).setDistanceUnit(DistanceUnit.foot); cmd.applyConfiguration(config); diff --git a/sao_paulo/src/main/java/org/eqasim/sao_paulo/RunSimulation.java b/sao_paulo/src/main/java/org/eqasim/sao_paulo/RunSimulation.java index 3e7d596ee..8ab5ac71d 100644 --- a/sao_paulo/src/main/java/org/eqasim/sao_paulo/RunSimulation.java +++ b/sao_paulo/src/main/java/org/eqasim/sao_paulo/RunSimulation.java @@ -28,8 +28,8 @@ static public void main(String[] args) throws ConfigurationException { .build(); EqasimConfigurator configurator = new EqasimConfigurator(); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configurator.getConfigGroups()); - configurator.addOptionalConfigGroups(config); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); EqasimConfigGroup.get(config).setAnalysisInterval(1); cmd.applyConfiguration(config); diff --git a/switzerland/src/main/java/org/eqasim/switzerland/RunSimulation.java b/switzerland/src/main/java/org/eqasim/switzerland/RunSimulation.java index 90ebe3686..29524f7aa 100644 --- a/switzerland/src/main/java/org/eqasim/switzerland/RunSimulation.java +++ b/switzerland/src/main/java/org/eqasim/switzerland/RunSimulation.java @@ -22,8 +22,8 @@ static public void main(String[] args) throws ConfigurationException { .build(); SwitzerlandConfigurator configurator = new SwitzerlandConfigurator(); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configurator.getConfigGroups()); - configurator.addOptionalConfigGroups(config); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path")); + configurator.updateConfig(config); cmd.applyConfiguration(config); if (cmd.hasOption("preventwaitingtoentertraffic")) { diff --git a/switzerland/src/main/java/org/eqasim/switzerland/scenario/RunAdaptConfig.java b/switzerland/src/main/java/org/eqasim/switzerland/scenario/RunAdaptConfig.java index 4e6b93247..4a26b68da 100644 --- a/switzerland/src/main/java/org/eqasim/switzerland/scenario/RunAdaptConfig.java +++ b/switzerland/src/main/java/org/eqasim/switzerland/scenario/RunAdaptConfig.java @@ -20,7 +20,7 @@ public class RunAdaptConfig { static public void main(String[] args) throws ConfigurationException { SwitzerlandConfigurator configurator = new SwitzerlandConfigurator(); - SwissConfigAdapter.run(args, configurator.getConfigGroups(), RunAdaptConfig::adaptConfiguration); + SwissConfigAdapter.run(args, configurator, RunAdaptConfig::adaptConfiguration); } static public void adaptConfiguration(Config config) { diff --git a/switzerland/src/main/java/org/eqasim/switzerland/scenario/SwissConfigAdapter.java b/switzerland/src/main/java/org/eqasim/switzerland/scenario/SwissConfigAdapter.java index 5cf771e52..9a366fa40 100644 --- a/switzerland/src/main/java/org/eqasim/switzerland/scenario/SwissConfigAdapter.java +++ b/switzerland/src/main/java/org/eqasim/switzerland/scenario/SwissConfigAdapter.java @@ -1,5 +1,6 @@ package org.eqasim.switzerland.scenario; +import org.eqasim.switzerland.SwitzerlandConfigurator; import org.matsim.core.config.*; import java.util.Arrays; @@ -14,7 +15,7 @@ public class SwissConfigAdapter { protected static double downsamplingRate = 1.0; protected static double replanningRate = 0.05; - public static void run(String[] args, ConfigGroup[] modules, Consumer adapter) + public static void run(String[] args, SwitzerlandConfigurator configurator, Consumer adapter) throws CommandLine.ConfigurationException { CommandLine cmd = new CommandLine.Builder(args) // .requireOptions("input-path", "output-path", "downsamplingRate", "replanningRate") // @@ -33,7 +34,8 @@ public static void run(String[] args, ConfigGroup[] modules, Consumer ad downsamplingRate = Double.parseDouble(cmd.getOptionStrict("downsamplingRate")); - Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("input-path"), modules); + Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("input-path")); + configurator.updateConfig(config); adapter.accept(config); new ConfigWriter(config).write(cmd.getOptionStrict("output-path"));