EpisimModule.java
/*-
* #%L
* MATSim Episim
* %%
* Copyright (C) 2020 matsim-org
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.matsim.episim;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.multibindings.Multibinder;
import org.matsim.api.core.v01.Scenario;
import org.matsim.core.api.experimental.events.EventsManager;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.config.groups.VspExperimentalConfigGroup;
import org.matsim.core.events.EventsUtils;
import org.matsim.core.scenario.ScenarioUtils;
import org.matsim.episim.model.*;
import org.matsim.episim.model.activity.ActivityParticipationModel;
import org.matsim.episim.model.activity.AllParticipationModel;
import org.matsim.episim.model.progression.DefaultDiseaseStatusTransitionModel;
import org.matsim.episim.model.progression.DiseaseStatusTransitionModel;
import org.matsim.episim.model.testing.DefaultTestingModel;
import org.matsim.episim.model.testing.TestingModel;
import org.matsim.episim.model.vaccination.RandomVaccination;
import org.matsim.episim.model.vaccination.VaccinationModel;
import org.matsim.episim.policy.FixedPolicy;
import org.matsim.episim.policy.ShutdownPolicy;
import org.matsim.episim.reporting.EpisimWriter;
import javax.inject.Named;
import java.util.SplittableRandom;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Provides the default bindings needed for Episim.
*/
public class EpisimModule extends AbstractModule {
@Override
protected void configure() {
binder().requireExplicitBindings();
// Main model classes regarding progression / infection etc..
bind(ContactModel.class).to(DefaultContactModel.class).in(Singleton.class);
bind(InfectionModel.class).to(DefaultInfectionModel.class).in(Singleton.class);
bind(ProgressionModel.class).to(ConfigurableProgressionModel.class).in(Singleton.class);
bind(AntibodyModel.class).to(DefaultAntibodyModel.class).in(Singleton.class);
bind(DiseaseStatusTransitionModel.class).to(DefaultDiseaseStatusTransitionModel.class).in(Singleton.class);
bind(FaceMaskModel.class).to(DefaultFaceMaskModel.class).in(Singleton.class);
bind(ShutdownPolicy.class).to(FixedPolicy.class).in(Singleton.class);
bind(InitialInfectionHandler.class).to(RandomInitialInfections.class).in(Singleton.class);
bind(VaccinationModel.class).to(RandomVaccination.class).in(Singleton.class);
bind(TestingModel.class).to(DefaultTestingModel.class).in(Singleton.class);
bind(ActivityParticipationModel.class).to(AllParticipationModel.class).in(Singleton.class);
// Internal classes, should rarely be needed to be reconfigured
bind(EpisimRunner.class).in(Singleton.class);
bind(ReplayHandler.class).in(Singleton.class);
bind(InfectionEventHandler.class).in(Singleton.class);
bind(EpisimReporting.class).in(Singleton.class);
bind(AntibodyModel.Config.class).toInstance(AntibodyModel.newConfig());
Multibinder.newSetBinder(binder(), SimulationListener.class);
Multibinder.newSetBinder(binder(), VaccinationModel.class);
}
@Provides
@Singleton
public Scenario scenario(Config config) {
// guice will use no args constructor by default, we check if this config was initialized
// this is only the case when no explicit binding are required
if (config.getModules().size() == 0)
throw new IllegalArgumentException("Please provide a config module or binding.");
config.vspExperimental().setVspDefaultsCheckingLevel(VspExperimentalConfigGroup.VspDefaultsCheckingLevel.ignore);
// save some time for not needed inputs
// config.facilities().setInputFile(null); // facilities are needed for location-based-restrictions
return ScenarioUtils.loadScenario(config);
}
@Provides
@Singleton
public EpisimConfigGroup episimConfigGroup(Config config) {
return ConfigUtils.addOrGetModule(config, EpisimConfigGroup.class);
}
@Provides
@Singleton
public TracingConfigGroup tracingConfigGroup(Config config) {
return ConfigUtils.addOrGetModule(config, TracingConfigGroup.class);
}
@Provides
@Singleton
public VaccinationConfigGroup vaccinationConfigGroup(Config config) {
return ConfigUtils.addOrGetModule(config, VaccinationConfigGroup.class);
}
@Provides
@Singleton
public TestingConfigGroup testingConfigGroup(Config config) {
return ConfigUtils.addOrGetModule(config, TestingConfigGroup.class);
}
@Provides
@Singleton
public VirusStrainConfigGroup strainConfigGroup(Config config) {
return ConfigUtils.addOrGetModule(config, VirusStrainConfigGroup.class);
}
@Provides
@Singleton
public EpisimWriter episimWriter(EpisimConfigGroup episimConfig) {
// TODO: needs to be fixed for single event files, synchronization after each iteration would be needed
// Async writer is used for huge event number
//if (Runtime.getRuntime().availableProcessors() > 1 && episimConfig.getWriteEvents() != EpisimConfigGroup.WriteEvents.episim)
// by default only one episim simulation is running
// return new AsyncEpisimWriter(1);
return new EpisimWriter();
}
@Provides
@Singleton
public EventsManager eventsManager() {
return EventsUtils.createEventsManager();
}
@Provides
@Singleton
public SplittableRandom splittableRandom(Config config) {
return new SplittableRandom(config.global().getRandomSeed());
}
@Provides
@Named("policy")
@Singleton
public com.typesafe.config.Config policyConfig(EpisimConfigGroup config) {
return config.getPolicy();
}
@Provides
@Singleton
public ExecutorService executorService(EpisimConfigGroup episimConfig) {
if (episimConfig.getThreads() > 1)
return Executors.newFixedThreadPool(episimConfig.getThreads());
else
return Executors.newSingleThreadScheduledExecutor();
}
}