diff --git a/.gitignore b/.gitignore index 8b2072c1b..8983b709a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,13 @@ .project .settings .vscode +.history target dependency-reduced-pom.xml *.iml *.idea simulation_output .vscode +._* +bavaria/data/* +nohup.out diff --git a/README.md b/README.md index 41f715012..c8a5d2433 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,112 @@ -# eqasim-java + +# How to run a MATSim simulation + +## 🚀 Running the MATSim Simulation + +This repo on the LRZ gitlab uses a pre-configured setup from eqasim's simulation repository. + +## ✅ Prerequisites + +1. Make sure you’ve completed all steps for generating the synthetic population. You find examples for the population synthesis output files on the internal drives: `\\10.152.34.30\Austausch\MATSim Populations` +2. Additional configuration details are available here: +👉 [https://github.com/eqasim-org/bavaria/blob/development-minga/docs/simulation.md](https://github.com/eqasim-org/bavaria/blob/development-minga/docs/simulation.md) + +--- + +### 1️⃣ Clone the Simulation Repository + +Use this repository and branch: + +- **Repository:** + 🔗 [https://gitlab.lrz.de/tum-vt/minga-eqasim-simulation](https://gitlab.lrz.de/tum-vt/minga-eqasim-simulation) + +- **Branch:** `bavaria-mode-choice` + 🔗 [https://gitlab.lrz.de/tum-vt/minga-eqasim-simulation/tree/bavaria-mode-choice](https://gitlab.lrz.de/tum-vt/minga-eqasim-simulation/tree/bavaria-mode-choice) + +Clone and check out the correct branch: + +```bash +git clone https://gitlab.lrz.de/tum-vt/minga-eqasim-simulation.git +cd eqasim-java +git checkout bavaria-mode-choice +``` + +--- + +### 2️⃣ (Optional) Create Your Own Branch Based on `bavaria-mode-choice` + +If you want to make changes or run your own experiments: + +```bash +git checkout -b my-example-experiment +git push -u origin my-example-experiment +``` + +This creates your own branch based on `bavaria-mode-choice` and sets up tracking so that future pushes and pulls work seamlessly. + +--- + +### 3️⃣ Prepare the `data` Folder + +In the `bavaria` module, create a `data` folder, containing the folder `munich` and copy your synthetic population and network files there: + +```bash +mkdir -p bavaria/data/munich +``` +Copy into this folder all files created in the synthetic population, such as the config, network file, etc. Only xml files are required! csv files are outputs of the MATSim simulation and are not used as inputs for the simulation. + +Ensure that you use a `config.xml` in which the eqasim:raptor parameters are set as follows: +``` + + + + + + + + + + +``` +You can use the config file that is used for calibration: `config_munich_calibrated.xml` from this repository. + +--- + +### 4️⃣ Run the Simulation + +First, build the project: +```bash +mvn clean package -Pstandalone --projects bavaria --also-make -DskipTests=true +``` + +This will generate a `bavaria-1.5.0.jar` file in the `bavaria/target` directory. + +To run a single simulation, use: + +```bash +nohup java -Xmx12G -cp bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulation --config-path bavaria/data/munich_0.1/munich_config.xml &> simulation_output.log & +``` +If you are running the simulation on a cluster or machine with larger memory resources, consider increasing the Java heap space, e.g., by setting -Xmx120G. + +If you want to run simulations for multiple random seeds, use the `RunSimulationsMultipleSeeds`, where you can specify the number of seeds, threads, and memory: +```bash +nohup java -cp bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulationsMultipleSeeds --seeds 3 --threads 12 --memory 60 > output.log 2>&1 & +``` + +This command works for all downsampled population sizes. +There’s no need to change the command based on population size — just ensure the corresponding population file is correctly referenced in the config. + +If you want to run MATSim on the LRZ cluster (e.g., cm4_tiny), you need to ask Peter for an account. After setting up your account, you can do the following steps to run the simulation: +1. Go to Windows PowerShell (or similar) and use the command `ssh @cool.hpc.lrz.de` to login. +2. Use the command `sbatch slurm_matsim_run_example.txt`. This file is part of this repo and can be copied. +3. `squeue -M cm4` tells you if your job is queued. +There are some restrictions on the LRZ cluster like the maximum of submitted jobs (currently 4), number of kernels etc. Find details to the LRZ cluster here: [https://doku.lrz.de/linux-cluster-10745672.html](https://doku.lrz.de/linux-cluster-10745672.html). + +In the `slurm_matsim_run_example.txt`file, there are some arguments for the mode choice parameter setting. These are **not** required since they are already correctly set in the `BavariaModeParameters.java` file. + + + +# eqasim-java [from the original readme] ![eqasim](docs/top.png "eqasim") diff --git a/bavaria/src/main/java/org/eqasim/bavaria/RunSimulation.java b/bavaria/src/main/java/org/eqasim/bavaria/RunSimulation.java index 53580d400..3d5bc539f 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/RunSimulation.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/RunSimulation.java @@ -3,6 +3,8 @@ import java.util.Collections; import java.util.Set; +import org.eqasim.bavaria.mode_choice.BavariaModeChoiceModule; +import org.eqasim.core.components.config.EqasimConfigGroup; import org.eqasim.core.scenario.validation.VehiclesValidator; import org.eqasim.core.simulation.vdf.VDFConfigGroup; import org.eqasim.core.simulation.vdf.engine.VDFEngineConfigGroup; @@ -48,6 +50,12 @@ static public void main(String[] args) throws ConfigurationException { cmd.applyConfiguration(config); VehiclesValidator.validate(config); + EqasimConfigGroup eqasimConfig = EqasimConfigGroup.get(config); + if (!eqasimConfig.getEstimators().get("walk").equals(BavariaModeChoiceModule.WALK_ESTIMATOR_NAME)) { + throw new IllegalArgumentException( + "Config needs to use bavariaWalk for mode choice. Please define BavariaWalkUtilityEstimator in estimators for mode walk."); + } + Scenario scenario = ScenarioUtils.createScenario(config); configurator.configureScenario(scenario); ScenarioUtils.loadScenario(scenario); diff --git a/bavaria/src/main/java/org/eqasim/bavaria/RunSimulationsMultipleSeeds.java b/bavaria/src/main/java/org/eqasim/bavaria/RunSimulationsMultipleSeeds.java new file mode 100644 index 000000000..f97e90c65 --- /dev/null +++ b/bavaria/src/main/java/org/eqasim/bavaria/RunSimulationsMultipleSeeds.java @@ -0,0 +1,189 @@ +package org.eqasim.bavaria; + +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.*; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * Runs multiple MATSim simulations for Munich using different random seeds, supporting parallel execution and automated output management. + * + * The class parses command line arguments to configure the number of seeds, thread count, and memory allocation. + * It sets up the necessary directories for Munich, manages concurrent simulation runs using a thread pool, and ensures that output directories are prepared and cleaned as needed. + * + * Example usage: + * nohup java -cp bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulationsMultipleSeeds > output.log 2>&1 & + * nohup java -cp bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulationsMultipleSeeds --seeds 3 --threads 12 --memory 60 > output.log 2>&1 & + * + * Note: After making changes to this class, recompile the project with: + * mvn clean package -Pstandalone --projects bavaria --also-make -DskipTests=true + */ + +public class RunSimulationsMultipleSeeds extends SimulationRunnerBase { + private static final Logger LOGGER = Logger.getLogger(RunSimulationsMultipleSeeds.class.getName()); + + static public void main(String[] args) throws Exception { + Config config; + try { + config = parseConfig(args); + } catch (IllegalArgumentException e) { + LOGGER.severe(e.getMessage()); + printUsage(); + System.exit(1); + return; // Never reached, but needed for compiler + } + + LOGGER.info("Running simulation with configuration: " + config); + + // Configuration settings + String configPath = "munich_config.xml"; + String workingDirectory = "bavaria/data/munich/"; + + LOGGER.info("Starting simulation with the following settings:"); + LOGGER.info("Configuration file: " + configPath); + LOGGER.info("Working directory: " + workingDirectory); + + // Create a fixed thread pool with specified number of threads + ExecutorService executor = Executors.newFixedThreadPool(config.threads); + LOGGER.info("Created thread pool with " + config.threads + " threads"); + + final String networkFile = "munich_network.xml.gz"; + LOGGER.info("Using network file: " + networkFile); + + final int currentSeed = config.numSeeds; + final String seedOutputDirectory = "bavaria/data/munich/output/seed_" + currentSeed + "/"; + LOGGER.info("Output for seed " + currentSeed + " will be written to: " + seedOutputDirectory); + + // Check if the output file exists for the current seed + boolean seedSimulationRanSuccessfully = checkIfFileExists(seedOutputDirectory, "output_events.xml.gz"); + LOGGER.info("Checking if output exists for seed " + currentSeed + ": " + seedSimulationRanSuccessfully); + + if (!seedSimulationRanSuccessfully) { + try { + if (outputDirectoryExists(seedOutputDirectory)) { + createAndEmptyDirectory(seedOutputDirectory); + LOGGER.info("Emptied output directory while preserving log files: " + seedOutputDirectory); + } else { + Files.createDirectories(Paths.get(seedOutputDirectory)); + LOGGER.info("Created output directory: " + seedOutputDirectory); + } + + // Submit task for the current seed + executor.submit(() -> { + LOGGER.info("Starting simulation task for: " + networkFile + " with seed " + currentSeed); + try { + runSimulation(configPath, networkFile, seedOutputDirectory, workingDirectory, args, currentSeed, + config.threads, config.threads, config.memory, true); + LOGGER.info("Completed simulation for: " + networkFile + " with seed " + currentSeed); + // If you want to keep only the three files output_links.csv.gz, output_events.xml.gz, and eqasim_trips.csv (for memory reasons), uncomment the following line. + // deleteUnwantedFiles(seedOutputDirectory); + // LOGGER.info("Deleted unwanted files for: " + networkFile + " with seed " + currentSeed); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + LOGGER.log(Level.SEVERE, "Simulation interrupted for: " + networkFile + " with seed " + currentSeed, e); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Error in simulation for: " + networkFile + " with seed " + currentSeed, e); + } + }); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Failed to setup output directory: " + seedOutputDirectory, e); + throw e; + } + } else { + LOGGER.info("Skipping simulation for seed " + currentSeed + " - output already exists in: " + seedOutputDirectory); + } + + // Shutdown the executor + executor.shutdown(); + try { + if (!executor.awaitTermination(300, TimeUnit.HOURS)) { + executor.shutdownNow(); + if (!executor.awaitTermination(360, TimeUnit.SECONDS)) { + LOGGER.severe("Executor did not terminate properly"); + } + } + } catch (InterruptedException ie) { + executor.shutdownNow(); + Thread.currentThread().interrupt(); + LOGGER.log(Level.SEVERE, "Executor was interrupted", ie); + } + LOGGER.info("All simulations completed"); + } + + /** + * Print usage instructions + */ + private static void printUsage() { + LOGGER.severe("Usage: java -cp bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulationsMultipleSeeds " + + "[--seeds ] [--threads ] " + + "[--memory ]"); + } + + /** + * Configuration class to hold all simulation parameters + */ + private static class Config { + int numSeeds = 3; // Default to 3 seeds + int threads = 12; // Default to 12 threads + int memory = 120; // Default to 60GB + + @Override + public String toString() { + return String.format("Config{numSeeds=%d, threads=%d, memory=%dGB}", + numSeeds, threads, memory); + } + } + + /** + * Parse and validate command line arguments + * @param args Command line arguments + * @return Config object with validated parameters + * @throws IllegalArgumentException if required parameters are missing or invalid + */ + private static Config parseConfig(String[] args) { + Config config = new Config(); + + for (int i = 0; i < args.length; i++) { + if (args[i].equals("--seeds") && i + 1 < args.length) { + try { + config.numSeeds = Integer.parseInt(args[i + 1]); + if (config.numSeeds < 1) { + throw new NumberFormatException("Number of seeds must be positive"); + } + i++; // Skip the next argument + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid number of seeds. Please provide a positive integer."); + } + } else if (args[i].equals("--threads") && i + 1 < args.length) { + try { + config.threads = Integer.parseInt(args[i + 1]); + if (config.threads < 1) { + throw new NumberFormatException("Number of threads must be positive"); + } + i++; // Skip the next argument + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid number of threads. Please provide a positive integer."); + } + } else if (args[i].equals("--memory") && i + 1 < args.length) { + try { + config.memory = Integer.parseInt(args[i + 1]); + if (config.memory < 1) { + throw new NumberFormatException("Memory allocation must be positive"); + } + i++; // Skip the next argument + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid memory allocation. Please provide a positive integer."); + } + } + } + return config; + } +} \ No newline at end of file diff --git a/bavaria/src/main/java/org/eqasim/bavaria/SimulationRunnerBase.java b/bavaria/src/main/java/org/eqasim/bavaria/SimulationRunnerBase.java new file mode 100644 index 000000000..2dea7c406 --- /dev/null +++ b/bavaria/src/main/java/org/eqasim/bavaria/SimulationRunnerBase.java @@ -0,0 +1,244 @@ +package org.eqasim.bavaria; + +import java.io.IOException; +import java.nio.file.*; +import java.util.concurrent.*; +import java.util.logging.*; + +import java.io.File; +import java.io.IOException; +import java.nio.file.*; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * This class contains helper functions for running simulations. + */ +public abstract class SimulationRunnerBase { + protected static final Logger LOGGER = Logger.getLogger(SimulationRunnerBase.class.getName()); + + /** + * Runs the MATSim simulation with a fixed random seed (1) for the different scenarios (not the base case). + */ + protected static void runSimulation(final String configPath, final String networkFile, final String outputDirectory, + final String workingDirectory, final String[] args, + final int numberOfThreads, + final int numberOfThreadsQSim, + final int memoryAllocation) throws Exception { + runSimulation(configPath, networkFile, outputDirectory, workingDirectory, args,1, numberOfThreads, numberOfThreadsQSim, memoryAllocation, false); + } + + /** + * Runs the MATSim simulation with the given configuration path and output directory. This is the main method, calling the class "RunSimulation". It can be called with different random seeds as for the base case, or for the scenarios. + * + * @param configPath The path to the configuration file. + * @param networkFile The network file to use for the simulation. + * @param outputDirectory The directory where output files will be stored. + * @param workingDirectory The working directory. + * @param args Command line arguments. + * @throws Exception if an error occurs during the simulation setup or execution. + */ + protected static void runSimulation(final String configPath, final String networkFile, final String outputDirectory, + final String workingDirectory, final String[] args, + final int randomSeed, + final int numberOfThreads, + final int numberOfThreadsQSim, + final int memoryAllocation, + final boolean isForBaseCase) throws Exception { + + String fullConfigPath = Paths.get(workingDirectory, configPath).toString(); + + final List arguments = new ArrayList<>(Arrays.asList( + "java", + "-Xms" + String.valueOf(memoryAllocation) + "g", + "-Xmx" + String.valueOf(memoryAllocation) + "g", + "-cp", + "bavaria/target/bavaria-1.5.0.jar", + "org.eqasim.bavaria.RunSimulation", + "--config:global.numberOfThreads", String.valueOf(numberOfThreads), + "--config:qsim.numberOfThreads", String.valueOf(numberOfThreadsQSim), + "--config:global.randomSeed", String.valueOf(randomSeed), + "--config:network.inputNetworkFile", networkFile, + "--config:controler.outputDirectory", outputDirectory, + "--config-path", fullConfigPath + )); + + System.out.println("Arguments for simulation:"); + for (String argument : arguments) { + System.out.println(argument); + } + File logFile = null ; + File errorLogFile = null; + if (isForBaseCase) { + logFile = new File("simulation_" + networkFile.replace("_network.xml.gz", "") + "_seed_" + randomSeed + ".log"); + errorLogFile = new File("simulation_" + networkFile.replace("_network.xml.gz", "") + "_seed_" + randomSeed + ".error.log"); + } else { + // for scenarios + String[] networkFileParts = networkFile.split("/"); + String fileName = networkFileParts[networkFileParts.length - 1]; + String[] fileNameParts = fileName.split("_"); + String city = networkFileParts[networkFileParts.length - 4]; + String primary = fileNameParts[3]; + String nValue = fileNameParts[4]; + String sValue = fileNameParts[5].replace(".xml.gz", ""); + String logFileName = "simulation_" + city + "_" + primary + "_" + nValue + "_" + sValue + ".log"; + logFile = new File(logFileName); + errorLogFile = new File("simulation_" + city + "_" + primary + "_" + nValue + "_" + sValue + ".error.log"); + } + System.out.println("Log file: " + logFile); + System.out.println("Error log file: " + errorLogFile); + + Process process = new ProcessBuilder(arguments) + .redirectOutput(logFile) + .redirectError(errorLogFile) + .start(); + System.out.println("Started process: " + outputDirectory); + + boolean interrupted = false; + try { + boolean finished = process.waitFor(3000, TimeUnit.HOURS); // Increase wait time + if (!finished) { + process.destroy(); // destroy process if it times out + throw new InterruptedException("Simulation process timed out: " + networkFile); + } + int exitValue = process.exitValue(); + if (exitValue != 0) { + throw new IOException("Simulation process failed with exit code " + exitValue + ": " + networkFile); + } + } catch (InterruptedException e) { + interrupted = true; + process.destroy(); // ensure process is destroyed if interrupted + throw e; // rethrow the exception to be handled in the calling method + } finally { + if (interrupted) { + Thread.currentThread().interrupt(); + } + } + LOGGER.info("Completed simulation for: " + networkFile); + } + + protected static void createAndEmptyDirectory(String directory) throws IOException { + Path dirPath = Paths.get(directory); + if (!Files.exists(dirPath)) { + Files.createDirectories(dirPath); + } else if (Files.isDirectory(dirPath)) { + try (DirectoryStream stream = Files.newDirectoryStream(dirPath)) { + for (Path entry : stream) { + String fileName = entry.getFileName().toString(); + // Preserve log files and essential output files + if (!fileName.equals("output_links.csv.gz")) { + deleteRecursively(entry); + } + } + } + } else { + throw new IOException("The path specified is not a directory: " + directory); + } + } + + protected static boolean checkIfFileExists(String directory, String fileName) { + Path dirPath = Paths.get(directory); + Path filePath = dirPath.resolve(fileName); + boolean exists = Files.exists(filePath) && !Files.isDirectory(filePath); + LOGGER.info("Checking if file exists: " + filePath + " - " + exists); + return exists; + } + + protected static Map> getNetworkFiles(String city, String directoryPath) { + File mainDirectory = new File(directoryPath); + File[] subDirs = mainDirectory.listFiles(File::isDirectory); + + if (subDirs == null) { + System.out.println("The specified directory does not exist or is not a directory."); + return Map.of(); + } + + return Arrays.stream(subDirs) + .collect(Collectors.toMap( + File::getName, + subDir -> { + File[] filesList = subDir.listFiles((dir, name) -> name.endsWith(".xml.gz")); + List xmlGzFiles = new ArrayList<>(); + if (filesList != null) { + for (File file : filesList) { + if (file.isFile()) { + xmlGzFiles.add(file.getName()); + } + } + // Sort the list of file names + Collections.sort(xmlGzFiles); + } + return xmlGzFiles; + } + )); + } + + + protected static boolean outputDirectoryExists(String outputDirectory) { + File dir = new File(outputDirectory); + boolean exists = dir.exists() && dir.isDirectory(); + LOGGER.info("Checking if output directory exists: " + outputDirectory + " - " + exists); + return exists; + } + + protected static void deleteUnwantedFiles(String outputDirectory) throws IOException { + Path dir = Paths.get(outputDirectory); + if (!Files.exists(dir)) { + LOGGER.warning("Output directory does not exist: " + outputDirectory); + return; + } + + try (DirectoryStream stream = Files.newDirectoryStream(dir)) { + for (Path path : stream) { + if (Files.isDirectory(path)) { + LOGGER.info("Deleting directory: " + path); + deleteDirectoryRecursively(path); + } else { + String fileName = path.getFileName().toString(); + if (!fileName.equals("output_links.csv.gz") + && !fileName.equals("output_events.xml.gz") + && !fileName.equals("eqasim_trips.csv")) { + Files.delete(path); + LOGGER.info("Deleted file: " + path); + } else { + LOGGER.info("Skipping file: " + path); + } + } + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error deleting files in directory: " + outputDirectory, e); + } + } + + protected static void deleteDirectoryRecursively(Path directory) throws IOException { + try (DirectoryStream stream = Files.newDirectoryStream(directory)) { + for (Path entry : stream) { + if (Files.isDirectory(entry)) { + deleteDirectoryRecursively(entry); + } else { + Files.delete(entry); + LOGGER.info("Deleted file: " + entry); + } + } + } + Files.delete(directory); + LOGGER.info("Deleted directory: " + directory); + } + + protected static void deleteRecursively(Path path) throws IOException { + if (Files.isDirectory(path)) { + try (DirectoryStream stream = Files.newDirectoryStream(path)) { + for (Path entry : stream) { + deleteRecursively(entry); + } + } + } + Files.delete(path); + } +} + diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/BavariaModeChoiceModule.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/BavariaModeChoiceModule.java index 77994338a..0a7f622b4 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/BavariaModeChoiceModule.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/BavariaModeChoiceModule.java @@ -14,6 +14,7 @@ import org.eqasim.bavaria.mode_choice.utilities.estimators.BavariaCarUtilityEstimator; import org.eqasim.bavaria.mode_choice.utilities.estimators.BavariaDrtUtilityEstimator; import org.eqasim.bavaria.mode_choice.utilities.estimators.BavariaPtUtilityEstimator; +import org.eqasim.bavaria.mode_choice.utilities.estimators.BavariaWalkUtilityEstimator; import org.eqasim.bavaria.mode_choice.utilities.predictors.BavariaCarPassengerPredictor; import org.eqasim.bavaria.mode_choice.utilities.predictors.BavariaPersonPredictor; import org.eqasim.bavaria.mode_choice.utilities.predictors.BavariaPtPredictor; @@ -44,6 +45,7 @@ public class BavariaModeChoiceModule extends AbstractEqasimExtension { public static final String CAR_PASSENGER_ESTIMATOR_NAME = "BavariaCarPassengerUtilityEstimator"; public static final String BICYCLE_ESTIMATOR_NAME = "BavariaBicycleUtilityEstimator"; public static final String PT_ESTIMATOR_NAME = "BavariaPtUtilityEstimator"; + public static final String WALK_ESTIMATOR_NAME = "BavariaWalkUtilityEstimator"; public static final String DRT_ESTIMATOR_NAME = "BavariaDrtUtilityEstimator"; static public final String CAR_PASSENGER = "car_passenger"; @@ -71,6 +73,7 @@ protected void installEqasimExtension() { bindUtilityEstimator(BICYCLE_ESTIMATOR_NAME).to(BavariaBicycleUtilityEstimator.class); bindUtilityEstimator(CAR_PASSENGER_ESTIMATOR_NAME).to(BavariaCarPassengerUtilityEstimator.class); bindUtilityEstimator(PT_ESTIMATOR_NAME).to(BavariaPtUtilityEstimator.class); + bindUtilityEstimator(WALK_ESTIMATOR_NAME).to(BavariaWalkUtilityEstimator.class); bindUtilityEstimator(DRT_ESTIMATOR_NAME).to(BavariaDrtUtilityEstimator.class); bind(ModeParameters.class).to(BavariaModeParameters.class); diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java index 1af560e5e..bd55e3b1a 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java @@ -3,59 +3,121 @@ import org.eqasim.core.simulation.mode_choice.parameters.ModeParameters; public class BavariaModeParameters extends ModeParameters { + + public class BavariaWalkParameters { + public double isHighIncome; + public double hasDrivingPermit; + public double hasPtSubscription; + public double isMunichResident; + } + + public class BavariaBicycleParameters { + public double isHighIncome; + } + + public class BavariaCarParameters { + public double isHighIncome; + public double hasPtSubscription; + public double isWorkTrip; + public double isShoppingTrip; + } + public class BavariaCarPassengerParameters { public double alpha_u; public double betaInVehicleTravelTime_u_min; public double betaDrivingPermit_u; + public double isHighIncome; + public double isWorkTrip; + public double isShoppingTrip; } - public final BavariaCarPassengerParameters carPassenger = new BavariaCarPassengerParameters(); - public class BavariaPtParameters { public double betaDrivingPermit_u; public double onlyBus_u; + public double isHighIncome; + public double waitingTimeHighIncome; + public double waitingTimeMunichResident; + public double waitingTimeSubscription; + public double waitingTimeShopping; + public double isWorkTrip; + public double isShoppingTrip; } + public final BavariaWalkParameters bavariaWalk = new BavariaWalkParameters(); + + public final BavariaBicycleParameters bavariaBicycle = new BavariaBicycleParameters(); + + public final BavariaCarParameters bavariaCar = new BavariaCarParameters(); + + public final BavariaCarPassengerParameters bavariaCarPassenger = new BavariaCarPassengerParameters(); + public final BavariaPtParameters bavariaPt = new BavariaPtParameters(); + public double betaAccessTime_u_min; public static BavariaModeParameters buildDefault() { BavariaModeParameters parameters = new BavariaModeParameters(); // Access - parameters.betaAccessTime_u_min = -0.031239; + // not specifically estimated for Bavaria, using values from walk.betaTravelTime_u_min + parameters.betaAccessTime_u_min = -0.0450421005231951; // IdF -0.031239; // Cost - parameters.betaCost_u_MU = -0.310998; - parameters.lambdaCostEuclideanDistance = -0.257501; + parameters.betaCost_u_MU = -0.0448921788117033; // IdF -0.310998; + parameters.lambdaCostEuclideanDistance = 0.0; // IdF -0.257501; parameters.referenceEuclideanDistance_km = 4.4; - // Car - parameters.car.alpha_u = 0.4; // -0.201465; - parameters.car.betaTravelTime_u_min = -0.042431; + - // Car passenger - parameters.carPassenger.alpha_u = -1.4; // -1.713201; - parameters.carPassenger.betaDrivingPermit_u = -0.835542; - parameters.carPassenger.betaInVehicleTravelTime_u_min = -0.069976; + // Walk + parameters.walk.alpha_u = -0.1; // uncalibrated 0.774228551231712; IdF 1.685152; + parameters.walk.betaTravelTime_u_min = -0.0695442805909274; // IdF -0.162285; + parameters.bavariaWalk.isHighIncome = -0.0217295300225373; + parameters.bavariaWalk.hasDrivingPermit = -0.0318551303397705; + parameters.bavariaWalk.hasPtSubscription = 0.0174505657228756; + parameters.bavariaWalk.isMunichResident = 0.0105573744916928; - // PT - parameters.pt.alpha_u = 0.0; - parameters.pt.betaLineSwitch_u = -0.417658; - parameters.pt.betaInVehicleTime_u_min = -0.025501; - parameters.pt.betaWaitingTime_u_min = -0.021801; - parameters.bavariaPt.betaDrivingPermit_u = -0.531426; - parameters.bavariaPt.onlyBus_u = -1.416309; + // Bicycle + parameters.bike.alpha_u = -1.2; // uncalibrated 0.318089528187347; IdF -2.927596; + parameters.bike.betaTravelTime_u_min = -0.085880877435606; // IdF -0.093485; + parameters.bavariaBicycle.isHighIncome = -0.0255287460190827; - // Bike - parameters.bike.alpha_u = -0.5; // -2.927596; - parameters.bike.betaTravelTime_u_min = -0.093485; + + // Car + parameters.car.alpha_u = 0.0; // IdF -0.201465; + parameters.car.betaTravelTime_u_min = -0.0756368247750132; // IdF -0.042431; + parameters.bavariaCar.isHighIncome = -0.0224982297973797; + parameters.bavariaCar.hasPtSubscription = -0.0539508519243061; + parameters.bavariaCar.isWorkTrip = 0.043746300263639; + parameters.bavariaCar.isShoppingTrip = 0.0681864158380864; + + // Car passenger + parameters.bavariaCarPassenger.alpha_u = -1.75; // uncalibrated -2.22497369171908; IdF -1.713201; + parameters.bavariaCarPassenger.betaDrivingPermit_u = 0.0; // IdF -0.835542; + parameters.bavariaCarPassenger.betaInVehicleTravelTime_u_min = -0.1; // uncalibrated -0.065198856305705; IdF -0.069976; + parameters.bavariaCarPassenger.isHighIncome = -0.0398473945616337; + parameters.bavariaCarPassenger.isWorkTrip = 0.0209967096068355; + parameters.bavariaCarPassenger.isShoppingTrip = 0.0508046089649204; + + + // PT + parameters.pt.alpha_u = -0.36; // uncalibrated -0.284650026405347; IdF 0.0; + parameters.pt.betaLineSwitch_u = -0.625046612374831; // IdF -0.417658; + parameters.pt.betaInVehicleTime_u_min = -0.03603368; // uncalibrated -0.0450421005231951; -IdF 0.025501; + parameters.pt.betaWaitingTime_u_min = -0.41123926919253; // IdF -0.021801; + + parameters.bavariaPt.betaDrivingPermit_u = 0.0; // IdF -0.531426; + parameters.bavariaPt.onlyBus_u = 0.0; // IdF -1.416309; + parameters.bavariaPt.isHighIncome = -0.0173904643343145; + parameters.bavariaPt.isWorkTrip = 0.0425817408468503; + parameters.bavariaPt.isShoppingTrip = 0.0441399147197244; + parameters.bavariaPt.waitingTimeShopping = -0.105687502807207; + parameters.bavariaPt.waitingTimeHighIncome = -0.152965571520264; + parameters.bavariaPt.waitingTimeMunichResident = 0.0990869975359573; + parameters.bavariaPt.waitingTimeSubscription = 0.413200821337636; - // Walk - parameters.walk.alpha_u = 1.8; // 1.685152; - parameters.walk.betaTravelTime_u_min = -0.162285; return parameters; } diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java index bc13c74fc..185debd40 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java @@ -3,6 +3,8 @@ import java.util.List; import org.eqasim.bavaria.mode_choice.parameters.BavariaModeParameters; +import org.eqasim.bavaria.mode_choice.utilities.predictors.BavariaPersonPredictor; +import org.eqasim.bavaria.mode_choice.utilities.variables.BavariaPersonVariables; import org.eqasim.core.simulation.mode_choice.utilities.estimators.BikeUtilityEstimator; import org.eqasim.core.simulation.mode_choice.utilities.predictors.BikePredictor; import org.eqasim.core.simulation.mode_choice.utilities.predictors.PersonPredictor; @@ -15,23 +17,32 @@ public class BavariaBicycleUtilityEstimator extends BikeUtilityEstimator { private final BavariaModeParameters parameters; + private final BavariaPersonPredictor bavariaPersonPredictor; @Inject - public BavariaBicycleUtilityEstimator(BavariaModeParameters parameters, PersonPredictor personPredictor, + public BavariaBicycleUtilityEstimator(BavariaModeParameters parameters, PersonPredictor personPredictor, BavariaPersonPredictor bavariaPersonPredictor, BikePredictor predictor) { super(parameters, personPredictor, predictor); this.parameters = parameters; + this.bavariaPersonPredictor = bavariaPersonPredictor; } protected double estimateAccessEgressTimeUtility(CarVariables variables) { return parameters.betaAccessTime_u_min * variables.accessEgressTime_min; } + protected double estimateHighIncomeUtility(BavariaPersonVariables variables) { + return variables.isHighIncome ? parameters.bavariaBicycle.isHighIncome : 0.0; + } + @Override public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { + BavariaPersonVariables personVariables = bavariaPersonPredictor.predictVariables(person, trip, elements); + double utility = 0.0; utility += super.estimateUtility(person, trip, elements); + utility += estimateHighIncomeUtility(personVariables); return utility; } diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarPassengerUtilityEstimator.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarPassengerUtilityEstimator.java index f826705c9..91d724a5c 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarPassengerUtilityEstimator.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarPassengerUtilityEstimator.java @@ -28,11 +28,11 @@ public BavariaCarPassengerUtilityEstimator(BavariaModeParameters parameters, Bav } protected double estimateConstantUtility() { - return parameters.carPassenger.alpha_u; + return parameters.bavariaCarPassenger.alpha_u; } protected double estimateTravelTimeUtility(BavariaCarPassengerVariables variables) { - return parameters.carPassenger.betaInVehicleTravelTime_u_min * variables.travelTime_min; + return parameters.bavariaCarPassenger.betaInVehicleTravelTime_u_min * variables.travelTime_min; } protected double estimateAccessEgressTimeUtility(BavariaCarPassengerVariables variables) { @@ -40,7 +40,19 @@ protected double estimateAccessEgressTimeUtility(BavariaCarPassengerVariables va } protected double estimateDrivingPermit(BavariaPersonVariables variables) { - return variables.hasDrivingPermit ? parameters.carPassenger.betaDrivingPermit_u : 0.0; + return variables.hasDrivingPermit ? parameters.bavariaCarPassenger.betaDrivingPermit_u : 0.0; + } + + protected double estimaleHighIncomeUtility(BavariaPersonVariables variables) { + return variables.isHighIncome ? parameters.bavariaCarPassenger.isHighIncome : 0.0; + } + + protected double estimateWorkPurposeUtility(DiscreteModeChoiceTrip trip) { + return trip.getDestinationActivity().getType().equals("work") ? parameters.bavariaCarPassenger.isWorkTrip : 0.0; + } + + protected double estimateShoppingPurposeUtility(DiscreteModeChoiceTrip trip) { + return trip.getDestinationActivity().getType().equals("shop") ? parameters.bavariaCarPassenger.isShoppingTrip : 0.0; } @Override @@ -54,6 +66,9 @@ public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements, List previousTrips) { - CarVariables variables = predictor.predictVariables(person, trip, elements, previousTrips); + CarVariables variables = predictor.predictVariables(person, trip, elements, previousTrip); + BavariaPersonVariables personVariables = personPredictor.predictVariables(person, trip, elements); double utility = 0.0; - + utility += estimateConstantUtility(); utility += estimateTravelTimeUtility(variables); utility += estimateAccessEgressTimeUtility(variables); utility += estimateMonetaryCostUtility(variables); + utility += estimateHighIncomeUtility(personVariables); + utility += estimatePtSubscriptionUtility(personVariables); + utility += estimateWorkPurposeUtility(trip); + utility += estimateShoppingPurposeUtility(trip); return utility; } diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaPtUtilityEstimator.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaPtUtilityEstimator.java index f442cfd86..6ccce1161 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaPtUtilityEstimator.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaPtUtilityEstimator.java @@ -44,8 +44,31 @@ protected double estimateLineSwitchUtility(BavariaPtVariables variables) { return parameters.pt.betaLineSwitch_u * variables.numberOfLineSwitches; } - protected double estimateWaitingTimeUtility(BavariaPtVariables variables) { - return parameters.pt.betaWaitingTime_u_min * variables.waitingTime_min; + protected double estimateWaitingTimeUtility(BavariaPtVariables ptVariables, BavariaPersonVariables personVariables, + DiscreteModeChoiceTrip trip) + { + double waitingTime_min = parameters.pt.betaWaitingTime_u_min; + if (personVariables.isHighIncome) { + waitingTime_min += parameters.bavariaPt.waitingTimeHighIncome; + } + if (personVariables.isMunichResident) { + waitingTime_min += parameters.bavariaPt.waitingTimeMunichResident; + } + if (personVariables.hasSubscription) { + waitingTime_min += parameters.bavariaPt.waitingTimeSubscription; + } + if (trip.getDestinationActivity().getType().equals("shop")) { + waitingTime_min += parameters.bavariaPt.waitingTimeShopping; + } + return waitingTime_min * ptVariables.waitingTime_min; + } + + protected double estimateWorkPurposeUtility(DiscreteModeChoiceTrip trip) { + return trip.getDestinationActivity().getType().equals("work") ? parameters.bavariaPt.isWorkTrip : 0.0; + } + + protected double estimateShoppingPurposeUtility(DiscreteModeChoiceTrip trip) { + return trip.getDestinationActivity().getType().equals("shop") ? parameters.bavariaPt.isShoppingTrip : 0.0; } protected double estimateMonetaryCostUtility(BavariaPtVariables variables, double cost_EUR) { @@ -61,6 +84,10 @@ protected double estimateDrivingPermitUtility(BavariaPersonVariables variables) return variables.hasDrivingPermit ? parameters.bavariaPt.betaDrivingPermit_u : 0.0; } + protected double estimateHighIncomeUtility(BavariaPersonVariables variables) { + return variables.isHighIncome ? parameters.bavariaPt.isHighIncome : 0.0; + } + protected double estimateOnlyBus(BavariaPtVariables variables) { return variables.isOnlyBus ? parameters.bavariaPt.onlyBus_u : 0.0; } @@ -77,12 +104,14 @@ public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { + BavariaPersonVariables personVariables = personPredictor.predictVariables(person, trip, elements); + + double utility = 0.0; + + utility += super.estimateUtility(person, trip, elements); + utility += estimateHighIncomeUtility(personVariables); + utility += estimateDrivingPermitUtility(personVariables); + utility += estimatePtSubscriptionUtility(personVariables); + utility += estimateMunichResidentUtility(personVariables); + + return utility; + } +} diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/predictors/BavariaPersonPredictor.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/predictors/BavariaPersonPredictor.java index 9cc79208f..870c55ddf 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/predictors/BavariaPersonPredictor.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/predictors/BavariaPersonPredictor.java @@ -14,6 +14,8 @@ protected BavariaPersonVariables predict(Person person, DiscreteModeChoiceTrip t List elements) { boolean hasSubscription = BavariaPredictorUtils.hasSubscription(person); boolean hasDrivingPermit = BavariaPredictorUtils.hasDrivingLicense(person); - return new BavariaPersonVariables(hasSubscription, hasDrivingPermit); + boolean isHighIncome = BavariaPredictorUtils.isHighIncome(person); + boolean isMunichResident = BavariaPredictorUtils.isMunichResident(person); + return new BavariaPersonVariables(hasSubscription, hasDrivingPermit, isHighIncome, isMunichResident); } } diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/predictors/BavariaPredictorUtils.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/predictors/BavariaPredictorUtils.java index 0e15836a4..966fee578 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/predictors/BavariaPredictorUtils.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/predictors/BavariaPredictorUtils.java @@ -18,6 +18,16 @@ static public boolean hasDrivingLicense(Person person) { return !"no".equals(PersonUtils.getLicense(person)); } + static public boolean isHighIncome(Person person) { + Boolean highIncome = (Boolean) person.getAttributes().getAttribute("highIncome"); + return highIncome != null && highIncome; + } + + static public boolean isMunichResident(Person person) { + Boolean isMunichResident = (Boolean) person.getAttributes().getAttribute("isMunichResident"); + return isMunichResident != null && isMunichResident; + } + static public boolean hasCarAvailability(Person person) { return !"none".equals((String) person.getAttributes().getAttribute("carAvailability")); } diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/variables/BavariaPersonVariables.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/variables/BavariaPersonVariables.java index 1608b1662..bd202b668 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/variables/BavariaPersonVariables.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/variables/BavariaPersonVariables.java @@ -5,9 +5,13 @@ public class BavariaPersonVariables implements BaseVariables { public final boolean hasSubscription; public final boolean hasDrivingPermit; + public final boolean isHighIncome; + public final boolean isMunichResident; - public BavariaPersonVariables(boolean hasSubscription, boolean hasDrivingPermit) { + public BavariaPersonVariables(boolean hasSubscription, boolean hasDrivingPermit, boolean isHighIncome, boolean isMunichResident) { this.hasSubscription = hasSubscription; this.hasDrivingPermit = hasDrivingPermit; + this.isHighIncome = isHighIncome; + this.isMunichResident = isMunichResident; } } diff --git a/bavaria/src/main/java/org/eqasim/bavaria/scenario/RunAdaptConfig.java b/bavaria/src/main/java/org/eqasim/bavaria/scenario/RunAdaptConfig.java index e42f42552..40a316ff5 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/scenario/RunAdaptConfig.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/scenario/RunAdaptConfig.java @@ -63,8 +63,11 @@ static public void adaptConfiguration(Config config, String prefix) { eqasimConfig.setEstimator(TransportMode.car, BavariaModeChoiceModule.CAR_ESTIMATOR_NAME); eqasimConfig.setEstimator(TransportMode.pt, BavariaModeChoiceModule.PT_ESTIMATOR_NAME); + eqasimConfig.setEstimator(BavariaModeChoiceModule.BICYCLE, BavariaModeChoiceModule.BICYCLE_ESTIMATOR_NAME); eqasimConfig.setEstimator(BavariaModeChoiceModule.CAR_PASSENGER, BavariaModeChoiceModule.CAR_PASSENGER_ESTIMATOR_NAME); + eqasimConfig.setEstimator(TransportMode.walk, BavariaModeChoiceModule.WALK_ESTIMATOR_NAME); + eqasimConfig.removeEstimator(TransportMode.bike); // Discrete mode choice diff --git a/config_munich_calibrated.xml b/config_munich_calibrated.xml new file mode 100644 index 000000000..6aa2410ff --- /dev/null +++ b/config_munich_calibrated.xml @@ -0,0 +1,908 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/simulation_bavaria.sbatch b/simulation_bavaria.sbatch new file mode 100644 index 000000000..708a09f32 --- /dev/null +++ b/simulation_bavaria.sbatch @@ -0,0 +1,33 @@ +#!/bin/bash + +#SBATCH -J simulation_bavaria_job + +# Output and error files +#SBATCH --output=simulation_bavaria_output_%j.log +#SBATCH --error=simulation_bavaria_error_%j.log + +#SBATCH --nodes=1 +#SBATCH --ntasks-per-node=1 +#SBATCH --cpus-per-task=12 +#SBATCH --mem=80GB +#SBATCH --time=00:30:00 + +# Account and partition +#SBATCH --account=pn39mu +#SBATCH --partition=test + +# Notification and type +#SBATCH --mail-type=BEGIN,END +#SBATCH --mail-user=elena.natterer@tum.de +#SBATCH --get-user-env + +# Set up of execution environment +#SBATCH --export=none + +#export HOME=/dss/dsshome1/06/ge49wav3 +export FONTCONFIG_PATH=$HOME/test_java_font_4u/fonts +export FONTCONFIG_FILE=$HOME/test_java_font_4u/fonts/fonts.conf +export FC_FONT_PATH=$HOME/test_java_font_4u/fonts + +# Run the Java program with full arguments +java -cp bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulationsMultipleSeeds --seeds 3 --threads 12 --memory 80 diff --git a/slurm_matsim_run_example.txt b/slurm_matsim_run_example.txt new file mode 100644 index 000000000..b1fe705bc --- /dev/null +++ b/slurm_matsim_run_example.txt @@ -0,0 +1,25 @@ +#!/bin/bash +#SBATCH -J calibrated # Job name (max 10 characters!) +#SBATCH -D /dss/dsshome1/0B/go68qak2/minga-eqasim-simulation +#SBATCH --mem=200G # Memory +#SBATCH --clusters=cm4 +#SBATCH --partition=cm4_tiny +#SBATCH --qos=cm4_tiny +#SBATCH --nodes=1 +#SBATCH --tasks-per-node=4 +#SBATCH --cpus-per-task=10 # Optional: how many cores +#SBATCH --time=08:00:00 # Time limit (hh:mm:ss) +#SBATCH --mail-user=your.name@tum.de # REQUIRED: your email address +#SBATCH --mail-type=BEGIN,END,FAIL # Send email when job ends or fails +#SBATCH --output=/dss/dsshome1/0B/go68qak2/minga-eqasim-simulation/simulation_bavaria_output_%j.log +#SBATCH --error=/dss/dsshome1/0B/go68qak2/simulation_bavaria_error_%j.log +#SBATCH --export=NONE # Recommended: clean environment +#SBATCH --get-user-env + +# Load modules +module load slurm_setup +module load openjdk/21.0.3_9 + +# Run your job +# You have to change the paths +srun java -cp /dss/dsshome1/0B/go68qak2/minga-eqasim-simulation/bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulation --config-path /dss/dsshome1/0B/go68qak2/minga-eqasim-simulation/bavaria/data/munich/munich_0.01/munich_config_calibrated.xml --use-vdf true --mode-choice-parameter:walk.alpha_u -0.1 --mode-choice-parameter:bike.alpha_u -1.2 --mode-choice-parameter:bavariaCarPassenger.alpha_u -1.75 --mode-choice-parameter:pt.alpha_u -0.36 --mode-choice-parameter:bavariaCarPassenger.betaInVehicleTravelTime_u_min -0.1 --mode-choice-parameter:pt.betaInVehicleTime_u_min -0.03603368 \ No newline at end of file