2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit a1a48e0b authored by Daniel Lehmberg's avatar Daniel Lehmberg
Browse files

Merge branch...

Merge branch '241-new-flag-to-compute-metric-for-the-quality-of-the-stepcircleoptimizer' into 'master'

Resolve "New flag to compute metric for the quality of the StepCircleOptimizer"

Closes #256 and #241

See merge request !65
parents d6a4b916 39a5d8e3
Pipeline #139605 passed with stages
in 122 minutes and 44 seconds
......@@ -34,6 +34,7 @@ __pycache__/
Tools/VadereAnalysisTools/VadereAnalysisTool/vadereanalysistool.egg-info/
Tools/VadereAnalysisTools/VadereAnalysisTool/build/
Tools/VadereAnalysisTools/VadereAnalysisTool/dist/
.mypy_cache/
# Jupyter Notebooks
**/.ipynb_checkpoints
......
......@@ -65,6 +65,7 @@ stages:
.template_scenario_files:
stage: integration_test
script:
- rm ~/.config/vadere.conf
- mvn clean
- mvn -Dmaven.test.skip=true package
- python3 Tools/ContinuousIntegration/run_vadere_console_with_all_scenario_files.py
......
......@@ -9,6 +9,7 @@
# python Tools/my_script.py
import argparse
import copy
import fnmatch
import os
import re
......@@ -19,15 +20,18 @@ import time
long_timeout_in_seconds = 12 * 60
short_timeout_in_seconds = 2 * 60
def parse_command_line_arguments():
parser = argparse.ArgumentParser(description="Run all scenario files.")
parser.add_argument("scenario", type=str, nargs="?", help="Run only the given scenario file and not all. E.g., \"VadereModelTests/TestOSM/scenarios/basic_2_density_discrete_ca.scenario\"")
args = parser.parse_args()
parser.add_argument("scenario", type=str, nargs="?",
help="Run only the given scenario file and not all. E.g., "
"\"VadereModelTests/TestOSM/scenarios/basic_2_density_discrete_ca.scenario\"")
return parser.parse_args()
return args
def run_all():
def run_all_model_tests():
long_running_scenarios = [
"basic_4_1_wall_gnm1",
"queueing",
......@@ -45,21 +49,48 @@ def run_all():
excluded_scenarios = ["TestOVM", "output", "legacy"]
excluded_scenarios.extend(long_running_scenarios)
scenario_files_regular_length = find_scenario_files(exclude_patterns=excluded_scenarios)
passed_and_failed_scenarios = run_scenario_files_with_vadere_console(scenario_files_regular_length, scenario_timeout_in_sec=short_timeout_in_seconds)
scenario_files_regular_length = find_scenario_files(path="VadereModelTests", exclude_patterns=excluded_scenarios)
passed_and_failed_scenarios = run_scenario_files_with_vadere_console(
scenario_files_regular_length, scenario_timeout_in_sec=short_timeout_in_seconds)
for scenario in long_running_scenarios:
search_pattern = "*" + scenario + "*.scenario"
scenario_files_long = find_scenario_files(scenario_search_pattern=search_pattern)
tmp_passed_and_failed_scenarios = run_scenario_files_with_vadere_console(scenario_files_long,
scenario_timeout_in_sec=long_timeout_in_seconds)
passed_and_failed_scenarios["passed"].extend(tmp_passed_and_failed_scenarios["passed"])
passed_and_failed_scenarios["failed"].extend(tmp_passed_and_failed_scenarios["failed"])
passed_and_failed_scenarios["failed_summary"].extend(tmp_passed_and_failed_scenarios["failed_summary"])
scenario_files_long = find_scenario_files(path="VadereModelTests", scenario_search_pattern=search_pattern)
tmp_passed_and_failed_scenarios = run_scenario_files_with_vadere_console(
scenario_files_long, scenario_timeout_in_sec=long_timeout_in_seconds)
passed_and_failed_scenarios = result_dict_merge(merge_into=passed_and_failed_scenarios,
merge_from=tmp_passed_and_failed_scenarios)
return passed_and_failed_scenarios
def run_all_optimization_tests():
scenario_files = find_scenario_files(path="VadereOptimizationTests")
# enables flag to compare optimization with brute force solution
config_filepath = os.path.join("VadereOptimizationTests", "TestNelderMead", "vadere.conf")
# NOTE: it is likely that the set config file is not required by new optimization tests
# long_timeout, because the brute force is expensive.
passed_and_failed_scenarios = run_scenario_files_with_vadere_console(
scenario_files, scenario_timeout_in_sec=long_timeout_in_seconds, config_filepath=config_filepath)
return passed_and_failed_scenarios
def find_scenario_files(path="VadereModelTests", scenario_search_pattern = "*.scenario", exclude_patterns = ["TestOVM", "output","legacy"]):
def find_scenario_files(path, scenario_search_pattern="*.scenario", exclude_patterns=None):
if exclude_patterns is None:
exclude_patterns = ["output", "legacy"] # default values
else: # always insert output and legacy
if "output" not in exclude_patterns:
exclude_patterns.append("output")
if "legacy" not in exclude_patterns:
exclude_patterns.append("legacy")
scenario_files = []
for root, dirnames, filenames in os.walk(path):
......@@ -73,12 +104,14 @@ def find_scenario_files(path="VadereModelTests", scenario_search_pattern = "*.sc
if match:
scenario_path_excluded = True
if scenario_path_excluded == False:
if not scenario_path_excluded:
scenario_files.append(scenario_path)
return sorted(scenario_files)
def run_scenario_files_with_vadere_console(scenario_files, vadere_console="VadereSimulator/target/vadere-console.jar", scenario_timeout_in_sec=short_timeout_in_seconds):
def run_scenario_files_with_vadere_console(scenario_files, vadere_console="VadereSimulator/target/vadere-console.jar",
scenario_timeout_in_sec=short_timeout_in_seconds, config_filepath=None):
output_dir = "output"
log_base_dir = "vadere_logs"
......@@ -94,7 +127,7 @@ def run_scenario_files_with_vadere_console(scenario_files, vadere_console="Vader
for i, scenario_file in enumerate(scenario_files):
try:
print("Running scenario file ({}/{}): {}".format(i + 1, total_scenario_files, scenario_file))
print(f"Running scenario file ({i + 1}/{total_scenario_files}): {scenario_file}")
# A scenario filename has the form "VadereModelTests/TestOSM/scenarios/chicken_floorfield_ok.scenario"
# Use second-level directory as subdirectory for logging (e.g., "TestOSM").
......@@ -104,21 +137,33 @@ def run_scenario_files_with_vadere_console(scenario_files, vadere_console="Vader
makedirs_if_non_existing(log_dir)
scenario_name = os.path.basename(scenario_file).split('.')[0]
log_file = os.path.join(log_dir, scenario_name + ".log")
log_file = os.path.join(log_dir, ".".join([scenario_name, "log"]))
print(" Log file: " + log_file)
# Measure wall time and not CPU time.
wall_time_start = time.time()
# Use timout feature, check return value and capture stdout/stderr to a PIPE (use completed_process.stdout to get it).
completed_process = subprocess.run(args=["java", "-enableassertions", "-jar", vadere_console,
"--logname", log_file, "scenario-run", "-f",
scenario_file, "-o", output_dir],
timeout=scenario_timeout_in_sec,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# Build subprocess args:
# Basic, always enable asserttions for tests
subprocess_args = ["java",
"-enableassertions",
"-jar", vadere_console,
"--logname", log_file]
# add config file if required
if config_filepath is not None:
subprocess_args += ["--config-file", config_filepath]
# run per scenario given the scenario path and output directory
subprocess_args += ["scenario-run", "-f", scenario_file, "-o", output_dir]
# Use timout feature, check return value and capture stdout/stderr to a PIPE (use completed_process.stdout
# to get it).
completed_process = subprocess.run(args=subprocess_args,
timeout=scenario_timeout_in_sec,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
wall_time_end = time.time()
wall_time_delta = wall_time_end - wall_time_start
......@@ -136,44 +181,50 @@ def run_scenario_files_with_vadere_console(scenario_files, vadere_console="Vader
except subprocess.CalledProcessError as exception:
print("Scenario file failed: {}".format(scenario_file))
print("-> Reason: non-zero return value {}".format(exception.returncode))
print(" {}".format(read_first_error_linies(exception.stderr)))
print(" {}".format(read_first_error_lines(exception.stderr)))
failed_summary.append("Scenario file failed: {}".format(scenario_file))
failed_summary.append("-> Reason: non-zero return value {}".format(exception.returncode))
failed_summary.append(" {}".format(read_first_error_linies(exception.stderr)))
failed_summary.append(" {}".format(read_first_error_lines(exception.stderr)))
failed_scenarios_with_exception.append((scenario_file, exception))
if os.path.exists(output_dir):
shutil.rmtree(output_dir)
return {"passed": passed_scenarios, "failed": failed_scenarios_with_exception, "failed_summary": failed_summary}
return result_dict_create(passed_scenarios, failed_scenarios_with_exception, failed_summary)
def makedirs_if_non_existing(directory):
if not os.path.exists(directory):
os.makedirs(directory)
def read_first_error_linies(error_byte_string):
def read_first_error_lines(error_byte_string):
err_string_lines = error_byte_string.decode('utf-8').split('\n')
if len(err_string_lines) >= 2:
return re.sub('\s+', ' ', ' '.join(err_string_lines[:2]))
else:
return 'unknown error see vadere log file.'
return 'Unknown error see Vadere log file.'
def result_dict_create(passed, failed, failed_summary):
return {"passed": passed, "failed": failed, "failed_summary": failed_summary}
def print_summary(passed_and_failed_scenarios):
def result_dict_print_summary(passed_and_failed_scenarios):
total_passed_scenarios = len(passed_and_failed_scenarios["passed"])
total_failed_scenarios = + len(passed_and_failed_scenarios["failed"])
total_failed_scenarios = len(passed_and_failed_scenarios["failed"])
total_scenarios = total_passed_scenarios + total_failed_scenarios
faild_summary = passed_and_failed_scenarios["failed_summary"]
failed_summary = passed_and_failed_scenarios["failed_summary"]
if len(faild_summary) > 0:
if result_dict_has_failed_tests(passed_and_failed_scenarios):
print("##################")
print("# Failed Summary #")
print("##################")
for line in faild_summary:
for line in failed_summary:
print(line)
print("###########")
print("# Summary #")
print("###########")
......@@ -182,17 +233,46 @@ def print_summary(passed_and_failed_scenarios):
print("Passed: {}".format(total_passed_scenarios))
print("Failed: {}".format(total_failed_scenarios))
def result_dict_has_failed_tests(passed_and_failed_scenarios):
return len(passed_and_failed_scenarios["failed"]) > 0
def result_dict_merge(merge_into, merge_from):
# both dict and list (values in result_dict) are mutable, so it is safer to make a copy of both and return a fresh
# instance
merge_into = copy.deepcopy(merge_into)
merge_from = copy.deepcopy(merge_from)
merge_into["failed"].extend(merge_from["failed"])
merge_into["passed"].extend(merge_from["passed"])
merge_into["failed_summary"].extend(merge_from["failed_summary"])
return merge_into
if __name__ == "__main__":
args = parse_command_line_arguments()
if args.scenario == None:
passed_and_failed_scenarios = run_all()
if args.scenario is None:
passed_and_failed_scenarios_model = run_all_model_tests()
if not result_dict_has_failed_tests(passed_and_failed_scenarios_model):
passed_and_failed_scenarios_optimization = run_all_optimization_tests()
else:
print("Skipping optimization tests...")
passed_and_failed_scenarios_optimization = {"failed": [], "passed": [], "failed_summary": []} # empty
# Make a summery of all scenario files
all_passed_and_failed_scenarios = result_dict_merge(passed_and_failed_scenarios_model,
passed_and_failed_scenarios_optimization)
else:
passed_and_failed_scenarios = run_scenario_files_with_vadere_console([args.scenario])
all_passed_and_failed_scenarios = run_scenario_files_with_vadere_console([args.scenario])
print_summary(passed_and_failed_scenarios)
result_dict_print_summary(all_passed_and_failed_scenarios)
if len(passed_and_failed_scenarios["failed"]) > 0:
if result_dict_has_failed_tests(all_passed_and_failed_scenarios):
exit(1)
else:
exit(0)
......@@ -80,7 +80,7 @@ public class ActionLoadProject extends AbstractAction {
} else {
logger.info(String.format("user canceled loadFromFilesystem project."));
logger.info("User canceled loadFromFilesystem project.");
}
} catch (IOException e1) {
e1.printStackTrace();
......@@ -88,24 +88,27 @@ public class ActionLoadProject extends AbstractAction {
}
public static void addToRecentProjects(String path) {
String listStr = VadereConfig.getConfig().getString("History.recentProjects", "");
String str = path; // make sure the new one is at top position
if (listStr.length() > 0) {
String[] list = listStr.split(",");
for (int i = 0; i < list.length; i++) {
String existingStoredPaths = VadereConfig.getConfig().getString("History.recentProjects", "");
String csvPaths = path; // make sure the new one is at top position -- comma separated paths
if (existingStoredPaths.length() > 0) {
String[] list = existingStoredPaths.split(",");
for(int i = 0; i < list.length; i++) {
String entry = list[i];
if (i < 10 && !entry.equals(path) && Files.exists(Paths.get(entry)))
str += "," + entry;
csvPaths += "," + entry;
}
}
VadereConfig.getConfig().setProperty("History.lastUsedProject", path);
VadereConfig.getConfig().setProperty("History.recentProjects", str);
VadereConfig.getConfig().setProperty("History.recentProjects", csvPaths);
ProjectView.getMainWindow().updateRecentProjectsMenu();
}
public static void loadProjectByPath(ProjectViewModel projectViewModel, String projectFilePath){
loadProjectByPath(projectViewModel, projectFilePath, MigrationOptions.defaultOptions());
}
public static void loadProjectByPath(ProjectViewModel projectViewModel, String projectFilePath, MigrationOptions options) {
try {
VadereProject project = IOVadere.readProjectJson(projectFilePath, options);
......
Test of Nelder Mead Optimiziation with Reference Scenarios
\ No newline at end of file
{
"name" : "basic_2_density_discrete_ca",
"description" : "",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile",
......@@ -60,6 +60,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......
{
"name" : "basic_2_density_pso",
"description" : "",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile",
......@@ -48,6 +48,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......
{
"name" : "chicken_floorfield_displaced_ok",
"description" : "",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile",
......@@ -59,6 +59,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......
{
"name" : "chicken_floorfield_ok",
"description" : "",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile",
......@@ -69,6 +69,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......
{
"name" : "corner_waiting_time_processor_test",
"description" : "",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.PedestrianIdOutputFile",
......@@ -69,6 +69,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......
{
"name" : "narrow_passage_discrete_CA_fail",
"description" : "",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile",
......@@ -51,6 +51,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......
{
"name" : "narrow_passage_nelder_mead_ok",
"description" : "",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile",
......@@ -67,6 +67,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 2.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......
{
"name" : "narrow_passage_pso_ok",
"description" : "",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile",
......@@ -67,6 +67,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 2.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......
{
"name" : "queueing_dynamic_floorfield_visual_check",
"description" : "",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile",
......@@ -43,6 +43,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "QUEUEING",
......
{
"name" : "regular_wall_discrete_ok",
"description" : "",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.PedestrianIdOutputFile",
......@@ -58,6 +58,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......
{
"name" : "regular_wall_nelder_mead_ok",
"description" : "",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.PedestrianIdOutputFile",
......@@ -58,6 +58,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......
{
"name" : "regular_wall_pso_ok",
"description" : "",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.PedestrianIdOutputFile",
......@@ -58,6 +58,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......
{
"name" : "rimea_01_pathway_discrete_brute_force",
"description" : "numberOfCircles = 4, stepCircleResolution = 30, DISCRETE",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.PedestrianIdOutputFile",
......@@ -68,6 +68,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......
{
"name" : "rimea_01_pathway_discrete_ca",
"description" : "numberOfCircles = 1, stepCircleResolution = 18, DISCRETE",
"release" : "1.1",
"release" : "1.2",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.PedestrianIdOutputFile",
......@@ -68,6 +68,8 @@
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"cacheType" : "NO_CACHE",
"cacheDir" : "",
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
......