/* * JABM - Java Agent-Based Modeling Toolkit * Copyright (C) 2013 Steve Phelps * * 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 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. */ package net.sourceforge.jabm; import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Properties; import net.sourceforge.jabm.spring.BeanFactorySingleton; import net.sourceforge.jabm.util.SystemProperties; import org.apache.log4j.Logger; import org.springframework.beans.factory.BeanFactory; /** * <p> * The main application class for JABM experiments when running in headless mode, * e.g. on a cluster (to run using a GUI see {@link net.sourceforge.jabm.DesktopSimulationManager}). * </p> * * <p> * Example usage:<br> * </p> * * <p> * <code>java -ea -server * -Djabm.config=config/elfarolbar.xml net.sourceforge.jabm.SimulationManager</code> * </p> * * <p> * System parameters: * </p> * * <p> * <table border="1"> * <tr> * <td><code>jabm.config</code></td> <td>The name of the Spring configuration file defining the simulation model</td> * </tr> * <tr> * <td><code>jabm.propertyfile</code></td> <td>The name of a properties file which overrides the values specified in the beans configuration</td> * </tr> * <tr> * <td><code>jabm.varfile</code></td> <td>The name of a properties file which specifies the ranges of independent variables to be used for a multiple treatment factor experiment</td> * </tr> * <td><code>jabm.configonly</code></td> <td>If set to true in combintation with jabm.varfile then create experiment property files without running any simulations. This is useful for running experiments on clusters. * </table> * * @see DesktopSimulationManager * * @author Steve Phelps */ public class SimulationManager implements Runnable { /** * The file name of the .properties file to use for the experiment(s). */ protected String propFile; /** * The (optional) file name of the variables file. The variables file * specifies a parameter sweep experiment in which the specified properties * are systematically varied over the specified ranges of values. */ protected String varFile; /** * The (optional) base directory in which subdirectories will be created * for experiments involving paramater sweeps. */ protected String baseDirName; /** * If this option is set, then the simulation manager will create * configuration files for experiments without actually running them. */ protected boolean configOnly; protected boolean generateSeeds; protected int seedMask; static Logger logger = Logger.getLogger(SimulationManager.class); /** * The name of the spring bean representing the SimulationController * which will be used to run the experiments. */ public static final String SIMULATION_CONTROLLER_BEAN = "simulationController"; public SimulationManager() { SystemProperties systemProperties = SystemProperties .jabsConfiguration(); propFile = systemProperties .getProperty(SystemProperties.PROPERTY_PROPFILE); varFile = systemProperties.getProperty( SystemProperties.PROPERTY_VARFILE); baseDirName = systemProperties.getProperty( SystemProperties.PROPERTY_BASE_DIR_NAME, "data"); configOnly = Boolean.parseBoolean(systemProperties.getProperty( SystemProperties.PROPERTY_CONFIG_ONLY, "false")); generateSeeds = Boolean.parseBoolean(systemProperties.getProperty( SystemProperties.PROPERTY_SEEDS, "false")); seedMask = Integer.parseInt(systemProperties.getProperty( SystemProperties.PROPERTY_SEED_MASK, "-1")); } @Override public void run() { if (propFile != null) { runSingleExperiment(propFile); } else { if (varFile != null) { setup(varFile, baseDirName, generateSeeds, seedMask); } else { if (configOnly) { setup(baseDirName, generateSeeds, seedMask); } else { runSingleExperiment(); } } } } public void launch(Runnable controller) { logger.info("Starting..."); long start = System.currentTimeMillis(); controller.run(); long finish = System.currentTimeMillis(); long duration = finish - start; logger.info("all done."); logger.info("completed simulation(s) in " + duration + "ms."); } public SimulationController getSimulationController() { return (SimulationController) BeanFactorySingleton .getBean(SIMULATION_CONTROLLER_BEAN); } public void runSingleExperiment() { launch(getSimulationController()); } public void runSingleExperiment(Properties properties) { SimulationExperiment experiment = new SimulationExperiment( properties); launch(experiment); } public void runSingleExperiment(String propFile) { try { logger.info("Running single experiment with properties " + propFile); Properties properties = new Properties(); properties.load(new FileInputStream(propFile)); runSingleExperiment(properties); return; } catch (IOException e) { throw new RuntimeException(e); } } public void setup(String baseDirName, boolean generateSeeds, int seedMask) { logger.info("Creating experiment with no variable bindings..."); logger.debug("baseDirName = " + baseDirName); BeanFactory beanFactory = BeanFactorySingleton.getBeanFactory(); Map<String, String> emptyBindings = new HashMap<String, String>(); SimulationExperiment experiment = new SimulationExperiment(beanFactory, baseDirName, 0, emptyBindings, generateSeeds, seedMask); experiment.createPropertyFile(); logger.info("done."); } public void setup(String varFile, String baseDirName, boolean generateSeeds, int seedMask) { logger.debug("baseDirName = " + baseDirName); long start = System.currentTimeMillis(); logger.info("Configuring experiments from " + varFile + " ..."); int experimentNumber = 0; BeanFactory beanFactory = BeanFactorySingleton.getBeanFactory(); VariableBindingsIterator iterator = new VariableBindingsIterator( varFile, beanFactory); while (iterator.hasNext()) { Map<String, String> bindings = iterator.next(); SimulationExperiment experiment = new SimulationExperiment( beanFactory, baseDirName, experimentNumber++, bindings, generateSeeds, seedMask); experiment.createPropertyFile(); } long finish = System.currentTimeMillis(); long duration = finish - start; logger.info("all done."); logger.info("Completed in " + duration + "ms."); } public static void main(String[] args) { SimulationManager manager = new SimulationManager(); manager.run(); } }