Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 7083c1b7 authored by Stefan Schuhbaeck's avatar Stefan Schuhbaeck
Browse files

add python script for seed test to gitlab pipeline

parent a4b9ca4b
Pipeline #76137 failed with stages
in 2 minutes and 53 seconds
......@@ -11,8 +11,9 @@ __pycache__/
*$py.class
**/venv/
Tools/VadereAnalysisTool/dist/
Tools/VadereAnalysisTool/build/
Tools/VadereAnalysisTool/VadereAnalysisTool.egg-info/
Tools/ContinuousIntegration/**/output
# C extensions
*.so
vadere_analysis_tool/build
......
......@@ -65,3 +65,12 @@ run_origin_test:
- python3 Tools/ContinuousIntegration/install_vadere_analysis_tool.py
- python3 Tools/ContinuousIntegration/run_orign_translation_test.py
run_seed_test:
stage: deploy
script:
- Documentation/version-control/git-hook-vadere-software
- mvn clean
- mvn -Dmaven.test.skip=true package
- python3 Tools/ContinuousIntegration/install_vadere_analysis_tool.py
- python3 Tools/ContinuousIntegration/run_seed_comparison_test.py
......@@ -21,9 +21,12 @@ def install_package_if_needed(package_name='VadereAnalysisTool', search_path='To
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
print("ReturnCode: {}\nStdOut: {} \nStdErr: {}".format(p_make_package.returncode,
p_make_package.stdout.decode('utf8'),
p_make_package.stderr.decode('utf8')))
if p_make_package.stdout:
print("StdOut: {}".format(p_make_package.stdout.decode('utf8')))
if p_make_package.stderr:
print("StdErr: {}".format(p_make_package.stderr.decode('utf8')))
print("ReturnCode: {}".format(p_make_package.returncode))
if p_make_package.returncode == 0:
stdout = p_make_package.stdout.decode('utf8')
dist_dir = os.path.join(search_path, "dist")
......@@ -41,9 +44,12 @@ def install_package_if_needed(package_name='VadereAnalysisTool', search_path='To
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
print("ReturnCode: {}\nStdOut: {} \nStdErr: {}".format(p_install_package.returncode,
p_install_package.stdout.decode('utf8'),
p_install_package.stderr.decode('utf8')))
if p_install_package.stdout:
print("StdOut: {}".format(p_install_package.stdout.decode('utf8')))
if p_install_package.stderr:
print("StdErr: {}".format(p_install_package.stderr.decode('utf8')))
print("ReturnCode: {}".format(p_install_package.returncode))
else:
exit(1)
else:
......
{
"name" : "2_bridge_coordinates_kai_unit_with_offset",
"description" : "",
"release" : "0.6",
"commithash" : "628b018374f404d2aca1afa3483e308428b6ae20",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile",
"filename" : "postvis.trajectories",
"processors" : [ 1, 2 ]
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOverlapOutputFile",
"filename" : "overlaps.csv",
"processors" : [ 3 ]
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.NoDataKeyOutputFile",
"filename" : "overlapCount.txt",
"processors" : [ 4 ]
} ],
"processors" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianPositionProcessor",
"id" : 1
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianTargetIdProcessor",
"id" : 2
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.PedestrianOverlapProcessor",
"id" : 3
}, {
"type" : "org.vadere.simulator.projects.dataprocessing.processor.NumberOverlapsProcessor",
"id" : 4,
"attributesType" : "org.vadere.state.attributes.processor.AttributesNumberOverlapsProcessor",
"attributes" : {
"pedestrianOverlapProcessorId" : 3
}
} ],
"isTimestamped" : true
},
"scenario" : {
"mainModel" : "org.vadere.simulator.models.osm.OptimalStepsModel",
"attributesModel" : {
"org.vadere.state.attributes.models.AttributesOSM" : {
"stepCircleResolution" : 18,
"numberOfCircles" : 1,
"varyStepDirection" : false,
"stepLengthIntercept" : 0.4625,
"stepLengthSlopeSpeed" : 0.2345,
"stepLengthSD" : 0.036,
"movementThreshold" : 0.0,
"optimizationType" : "NELDER_MEAD",
"movementType" : "ARBITRARY",
"dynamicStepLength" : false,
"updateType" : "EVENT_DRIVEN",
"seeSmallWalls" : false,
"minimumStepLength" : false,
"targetPotentialModel" : "org.vadere.simulator.models.potential.fields.PotentialFieldTargetGrid",
"pedestrianPotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldPedestrianCompactSoftshell",
"obstaclePotentialModel" : "org.vadere.simulator.models.potential.PotentialFieldObstacleCompactSoftshell",
"submodels" : [ ]
},
"org.vadere.state.attributes.models.AttributesPotentialCompactSoftshell" : {
"pedPotentialIntimateSpaceWidth" : 0.45,
"pedPotentialPersonalSpaceWidth" : 1.2,
"pedPotentialHeight" : 50.0,
"obstPotentialWidth" : 0.8,
"obstPotentialHeight" : 6.0,
"intimateSpaceFactor" : 1.2,
"personalSpacePower" : 1,
"intimateSpacePower" : 1
},
"org.vadere.state.attributes.models.AttributesFloorField" : {
"createMethod" : "HIGH_ACCURACY_FAST_MARCHING",
"potentialFieldResolution" : 0.1,
"obstacleGridPenalty" : 0.1,
"targetAttractionStrength" : 1.0,
"timeCostAttributes" : {
"standardDeviation" : 0.7,
"type" : "UNIT",
"obstacleDensityWeight" : 3.5,
"pedestrianSameTargetDensityWeight" : 3.5,
"pedestrianOtherTargetDensityWeight" : 3.5,
"pedestrianWeight" : 3.5,
"queueWidthLoading" : 1.0,
"pedestrianDynamicWeight" : 6.0,
"loadingType" : "CONSTANT"
}
}
},
"attributesSimulation" : {
"finishTime" : 200.0,
"simTimeStepLength" : 0.4,
"realTimeSimTimeRatio" : 0.0,
"writeSimulationData" : true,
"visualizationEnabled" : true,
"printFPS" : false,
"digitsPerCoordinate" : 2,
"useFixedSeed" : true,
"fixedSeed" : -5104110572817619091,
"simulationSeed" : 0
},
"topography" : {
"attributes" : {
"bounds" : {
"x" : 564280.0,
"y" : 5933391.0,
"width" : 50.0,
"height" : 50.0
},
"boundingBoxWidth" : 0.5,
"bounded" : true
},
"obstacles" : [ {
"shape" : {
"type" : "POLYGON",
"points" : [ {
"x" : 564330.2959240791,
"y" : 5933433.506680049
}, {
"x" : 564311.2959240791,
"y" : 5933433.506680049
}, {
"x" : 564300.9318720899,
"y" : 5933401.544835466
}, {
"x" : 564312.1291207125,
"y" : 5933396.936819093
}, {
"x" : 564330.1291207125,
"y" : 5933396.936819093
} ]
},
"id" : 1
}, {
"shape" : {
"type" : "POLYGON",
"points" : [ {
"x" : 564309.9431192318,
"y" : 5933389.478288522
}, {
"x" : 564309.9431192318,
"y" : 5933391.478288522
}, {
"x" : 564287.7114777192,
"y" : 5933401.030658626
}, {
"x" : 564280.3263510215,
"y" : 5933402.349890053
}, {
"x" : 564280.3263510215,
"y" : 5933390.349890053
} ]
},
"id" : 2
}, {
"shape" : {
"type" : "POLYGON",
"points" : [ {
"x" : 564283.8886836024,
"y" : 5933411.251412248
}, {
"x" : 564290.0683166787,
"y" : 5933406.240937642
}, {
"x" : 564295.4593781466,
"y" : 5933403.808810473
}, {
"x" : 564303.4638894079,
"y" : 5933436.907734532
}, {
"x" : 564280.4638894079,
"y" : 5933436.907734532
} ]
},
"id" : -1
} ],
"stairs" : [ ],
"targets" : [ {
"id" : 1,
"absorbing" : true,
"shape" : {
"type" : "POLYGON",
"points" : [ {
"x" : 564280.3,
"y" : 5933402.3
}, {
"x" : 564280.1,
"y" : 5933403.7
}, {
"x" : 564280.5,
"y" : 5933414.2
}, {
"x" : 564283.9,
"y" : 5933411.2
} ]
},
"waitingTime" : 0.0,
"waitingTimeYellowPhase" : 0.0,
"parallelWaiters" : 0,
"individualWaiting" : true,
"deletionDistance" : 0.1,
"startingWithRedLight" : false,
"nextSpeed" : -1.0
}, {
"id" : 1,
"absorbing" : true,
"shape" : {
"type" : "POLYGON",
"points" : [ {
"x" : 564313.9,
"y" : 5933391.2
}, {
"x" : 564309.9,
"y" : 5933391.5
}, {
"x" : 564312.3,
"y" : 5933397.0
}, {
"x" : 564316.4,
"y" : 5933395.9
} ]
},
"waitingTime" : 0.0,
"waitingTimeYellowPhase" : 0.0,
"parallelWaiters" : 0,
"individualWaiting" : true,
"deletionDistance" : 0.1,
"startingWithRedLight" : false,
"nextSpeed" : -1.0
} ],
"sources" : [ {
"id" : -1,
"shape" : {
"x" : 564304.3,
"y" : 5933435.5,
"width" : 8.0,
"height" : 4.4,
"type" : "RECTANGLE"
},
"interSpawnTimeDistribution" : "org.vadere.state.scenario.ConstantDistribution",
"distributionParameters" : [ 1.0 ],
"spawnNumber" : 4,
"maxSpawnNumberTotal" : -1,
"startTime" : 0.0,
"endTime" : 100.0,
"spawnAtRandomPositions" : false,
"useFreeSpaceOnly" : true,
"targetIds" : [ 1 ],
"groupSizeDistribution" : [ 1.0 ],
"dynamicElementType" : "PEDESTRIAN"
} ],
"dynamicElements" : [ ],
"attributesPedestrian" : {
"radius" : 0.195,
"densityDependentSpeed" : false,
"speedDistributionMean" : 1.34,
"speedDistributionStandardDeviation" : 0.26,
"minimumSpeed" : 0.5,
"maximumSpeed" : 2.2,
"acceleration" : 2.0
},
"attributesCar" : {
"id" : -1,
"radius" : 0.195,
"densityDependentSpeed" : false,
"speedDistributionMean" : 1.34,
"speedDistributionStandardDeviation" : 0.26,
"minimumSpeed" : 0.5,
"maximumSpeed" : 2.2,
"acceleration" : 2.0,
"length" : 4.5,
"width" : 1.7,
"direction" : {
"x" : 1.0,
"y" : 0.0
}
}
}
}
}
\ No newline at end of file
......@@ -2,7 +2,6 @@
"name" : "bridge_coordinates_kai",
"description" : "",
"release" : "0.6",
"commithash" : "topographyWarning: no commit hash",
"processWriters" : {
"files" : [ {
"type" : "org.vadere.simulator.projects.dataprocessing.outputfile.TimestepPedestrianIdOutputFile",
......@@ -96,7 +95,7 @@
"digitsPerCoordinate" : 2,
"useFixedSeed" : true,
"fixedSeed" : -3213925745664992646,
"simulationSeed" : -3213925745664992646
"simulationSeed" : 0
},
"topography" : {
"attributes" : {
......
import os
import shutil
import subprocess
import time
from vadere_analysis_tool import VadereProject
from vadere_analysis_tool import SameSeedTrajectory
def run_scenario_files_with_vadere_console(project, number_of_runs=3, vadere_console="VadereSimulator/target/vadere-console.jar",
scenario_timeout_in_sec=60*5):
scenario_files = project.scenario_files
total_scenario_files = len(scenario_files)
output_dir = project.output_path
passed_scenarios = []
failed_scenarios_with_exception = []
for run in range(number_of_runs):
for i, scenario_file in enumerate(scenario_files):
try:
scenario_name = os.path.basename(scenario_file)
print("Running scenario file ({}/{}) of run {}/{}: {}".format(i + 1, total_scenario_files, run + 1, number_of_runs, scenario_name))
# Measure wall time and not CPU time simply because it is the simplest method.
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).
# print("subprocess call: {}".format(' '.join(
# ["java", "-enableassertions", "-jar", vadere_console, "scenario-run", "-f", scenario_file, "-o", output_dir])))
completed_process = subprocess.run(
args=["java", "-enableassertions", "-jar", vadere_console, "scenario-run", "-f", scenario_file, "-o",
output_dir],
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
print("Finished scenario file ({:.1f} s): {}".format(wall_time_delta, scenario_file))
passed_scenarios.append(scenario_file)
except subprocess.TimeoutExpired as exception:
print("Scenario file failed: {}".format(scenario_file))
print("-> Reason: timeout after {} s".format(exception.timeout))
failed_scenarios_with_exception.append((scenario_file, exception))
except subprocess.CalledProcessError as exception:
print("Scenario file failed: {}".format(scenario_file))
print("-> Reason: non-zero return value {}".format(exception.returncode))
failed_scenarios_with_exception.append((scenario_file, exception))
return {"passed": passed_scenarios, "failed": failed_scenarios_with_exception}
if __name__ == '__main__':
project = VadereProject('Tools/ContinuousIntegration/run_seed_comparison_test.d')
project.clear_output_dir()
run_scenario_files_with_vadere_console(project)
# this will reload project
seed_test = SameSeedTrajectory('Tools/ContinuousIntegration/run_seed_comparison_test.d')
seed_results = seed_test.get_trajectory_comparison_result()
seed_err = [res for res in seed_results if not res['hash_is_equal']]
seed_ok = [res for res in seed_results if res['hash_is_equal']]
if seed_err:
for res in seed_err:
print("Scenario {} with scenario-hash {} - ERROR".format(res['scenario_name'], res['scenario_hash']))
for res_out in res['scenario_outputs']:
print(" {}--{}".format(res_out[1], res_out[0]))
if seed_ok:
for res in seed_ok:
print("Scenario {} with scenario-hash {} - OK".format(res['scenario_name'], res['scenario_hash']))
from vadere_analysis_tool.scenario_output import ScenarioOutput
from vadere_analysis_tool.scenario_output import NamedFiles
from vadere_analysis_tool.vadere_project import VadereProject
from vadere_analysis_tool.vadere_project import NamedOutput
from vadere_analysis_tool.analysis.origin_deviation import OriginDeviation
name = 'vadere_analysis_tool'
from vadere_analysis_tool.analysis.origin_deviation import OriginDeviation
\ No newline at end of file
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from vadere_analysis_tool import ScenarioOutput
class OriginDeviation:
""" Calculate deviation of origin after transforming it form 0 to X.
In output_pair a array like structure with output_pair[0] (no translation)
and output_pair[1] (with translation) is expected.
"""
def __init__(self, output_pair, name='', max_diff_ok=1e-7, max_diff_warn=1e-4):
self.output_pair = output_pair
self.max_diff_ok= max_diff_ok
self.max_diff_warn = max_diff_warn
self.df = pd.DataFrame()
self.name = name
self.get_origin_deviation_data()
def get_origin_deviation_data(self):
# Create ScenarioOutput object
out_0_origin = ScenarioOutput(self.output_pair[0])
out_offset_origin = ScenarioOutput(self.output_pair[1])
if self.name == '':
self.name = out_0_origin.output_dir_name + "---" + out_offset_origin.output_dir_name
# Load trajectories and offset
trajectory_0_orign = out_0_origin.files['postvis.trajectories']()
trajectory_offset_orign = out_offset_origin.files['postvis.trajectories']()
offset = out_offset_origin.get_bound_offset()
# Merge data frames and calculate differences after reverting offset transformation
df = pd.merge(trajectory_0_orign, trajectory_offset_orign, on=['timeStep', 'pedestrianId'],
suffixes=['_0', '_offset'])
df['x_trans'] = np.abs(df['x_offset'] - offset[0])
df['y_trans'] = np.abs(df['y_offset'] - offset[1])
df['x_diff'] = np.abs(df['x_0'] - (df['x_offset'] - offset[0]))
df['y_diff'] = np.abs(df['y_0'] - (df['y_offset'] - offset[1]))
df['diff'] = np.abs(np.sqrt(df.x_0 ** 2 + df.y_0 ** 2) - (np.sqrt(df.x_trans ** 2 + df.y_trans ** 2)))
# find maximal difference for each pedestrian in postvis.trajectories.
# df_max_diff_per_pedId contains one row per pedestrian
df_max_diff = df.loc[df.groupby('pedestrianId')['diff'].idxmax(),]
df_start_diff = df.loc[df.groupby('pedestrianId')['timeStep'].idxmin(),]
return df, df_max_diff, df_start_diff
def get_origin_deviation_result(self):
_, df_max_diff, df_start_diff = self.get_origin_deviation_data()
ped_id_warn = df_max_diff[(df_max_diff['diff'] > self.max_diff_ok) & (df_max_diff['diff'] <= self.max_diff_warn)].index.values
ped_id_err = df_max_diff[(df_max_diff['diff'] > self.max_diff_warn)].index.values
ped_id_ok_ = df_max_diff[(df_max_diff['diff'] <= self.max_diff_ok)].index.values
ret = {'err_count': len(ped_id_err), 'warn_count': len(ped_id_warn), 'ok_count': len(ped_id_ok_),
'err_dict': df_max_diff.loc[ped_id_err].to_dict('index'),
'warn_dict': df_max_diff.loc[ped_id_warn].to_dict('index'),
'stats_at_max_diff': df_max_diff['diff'].describe(), 'stats_at_start': df_start_diff['diff'].describe(),
'output_name': self.name, 'df_max_diff': df_max_diff, 'df_start_diff': df_start_diff
}
return ret
def get_figure(self, results):
width = 15
height = 4 * len(results)
fig, axes = plt.subplots(ncols=2, nrows=len(results), figsize=[width, height])
i = 0
for result in results:
self._add_axis(axes[i, 0], result['df_max_diff'], 'pedestrianId', 'diff',
title="MaxDiff " + result['output_name'],
yscale='log')
self._add_axis(axes[i, 1], result['df_start_diff'], 'pedestrianId', 'diff',
title="StartDiff " + result['output_name'],
yscale='log')
i += 1
return fig
@staticmethod
def _add_axis(ax, data, x_data_label, y_data_label, yscale='linear', title='', x_text_label='', y_text_label=''):
ax.plot(x_data_label, y_data_label, data=data, linestyle='', marker='.')
ax.set_yscale(yscale)
ax.set_title(title)
ax.set_xlabel(x_text_label)
ax.set_ylabel(y_text_label)
return ax
import os
import json
def read_lines(path):
if os.path.exists(path):
with open(path, 'r') as f:
return f.readlines()
else:
raise FileNotFoundError("File not found {}".format(path))
def read_json_to_dict(path):
if os.path.exists(path):
with open(path, 'r') as f:
return json.load(f)
else:
raise FileNotFoundError("File not found {}".format(path))
def clean_dir_name(dir_name):
ret = dir_name.replace('.', '_')
ret = ret.replace('-','_')
return ret
\ No newline at end of file