diff --git a/.gitignore b/.gitignore
index 9643d59e8..a6084f713 100644
--- a/.gitignore
+++ b/.gitignore
@@ -254,6 +254,10 @@ examples/experimental/logs/*
# Sbatch scripts
*.sh
+# Dataset
+wosac/
+other/
+
# Videos
videos/
output_videos_larger_dataset/
diff --git a/baselines/ppo/config/ppo_waypoint.yaml b/baselines/ppo/config/ppo_waypoint.yaml
index 7f44980b9..24b95d655 100644
--- a/baselines/ppo/config/ppo_waypoint.yaml
+++ b/baselines/ppo/config/ppo_waypoint.yaml
@@ -2,14 +2,14 @@ mode: "train"
use_rnn: false
eval_model_path: null
baseline: false
-data_dir: data/processed/wosac/validation_json_100
+data_dir: data/processed/wosac/validation_json_1
continue_training: false
model_cpt: null
environment: # Overrides default environment configs (see pygpudrive/env/config.py)
name: "gpudrive"
num_worlds: 100 # Number of parallel environments
- k_unique_scenes: 100 # Number of unique scenes to sample from
+ k_unique_scenes: 1 # Number of unique scenes to sample from
max_controlled_agents: 64 # Maximum number of agents controlled by the model. Make sure this aligns with the variable kMaxAgentCount in src/consts.hpp
ego_state: true
road_map_obs: true
@@ -84,7 +84,7 @@ train:
clip_coef: 0.2
clip_vloss: false
vf_clip_coef: 0.2
- ent_coef: 0.001
+ ent_coef: 0.005
vf_coef: 0.5
max_grad_norm: 0.5
target_kl: null
@@ -102,14 +102,14 @@ train:
num_parameters: 0 # Total trainable parameters, to be filled at runtime
# # # Checkpointing # # #
- checkpoint_interval: 500 # Save policy every k iterations
+ checkpoint_interval: 250 # Save policy every k iterations
checkpoint_path: "./runs"
# # # Rendering # # #
- render: false # Determines whether to render the environment (note: will slow down training)
+ render: true # Determines whether to render the environment (note: will slow down training)
render_3d: false # Render simulator state in 3d or 2d
- render_interval: 150 # Render every k iterations
- render_k_scenarios: 2 # Number of scenarios to render
+ render_interval: 200 # Render every k iterations
+ render_k_scenarios: 1 # Number of scenarios to render
render_format: "mp4" # Options: gif, mp4
render_fps: 20 # Frames per second
zoom_radius: 100
diff --git a/checkpoints/model_waypoint_rs__S_1__04_23_19_37_26_618_003500.pt b/checkpoints/model_waypoint_rs__S_1__04_23_19_37_26_618_003500.pt
new file mode 100644
index 000000000..138500377
Binary files /dev/null and b/checkpoints/model_waypoint_rs__S_1__04_23_19_37_26_618_003500.pt differ
diff --git a/data_utils/process_waymo_files.py b/data_utils/process_waymo_files.py
index 8c405c913..fa3bdc2d4 100644
--- a/data_utils/process_waymo_files.py
+++ b/data_utils/process_waymo_files.py
@@ -685,7 +685,7 @@ def process_data(args):
)
parser.add_argument(
"--id_as_filename",
- default=False,
+ default=True,
action="store_true",
help="Use the unique scenario id as the filename",
)
diff --git a/examples/eval/README.md b/examples/eval/README.md
new file mode 100644
index 000000000..78c321e8e
--- /dev/null
+++ b/examples/eval/README.md
@@ -0,0 +1,28 @@
+## Waymo Open Sim Agent Challenge (WOSAC) evaluation
+
+
+## Requirements
+Prerequisite
+```
+pip install --no-deps waymo-open-dataset-tf-2-12-0==1.6.4
+pip install --no-deps git+https://github.com/waymo-research/waymax.git@main#egg=waymo-waymax
+```
+
+## Dataset
+Extract TF example from raw waymo TF example dataset using
+```
+python examples/eval/extract_dataset.py --data_dir XXXX --save_dir xxxx --dataset [train/val/val_interactive]
+```
+
+e.g.
+
+```
+python examples/eval/extract_dataset.py --data_dir data/raw --save_dir data/processed/wosac --dataset all
+```
+
+
+## Evaluation
+Run eval with
+```
+python wosac_eval.py
+```
diff --git a/data/raw/.gitkeep b/examples/eval/__init__.py
similarity index 100%
rename from data/raw/.gitkeep
rename to examples/eval/__init__.py
diff --git a/examples/eval/extract_dataset.py b/examples/eval/extract_dataset.py
new file mode 100644
index 000000000..b85911652
--- /dev/null
+++ b/examples/eval/extract_dataset.py
@@ -0,0 +1,137 @@
+import os
+# Force JAX to use CPU only
+os.environ["JAX_PLATFORMS"] = "cpu"
+
+import tensorflow as tf
+import glob
+import argparse
+# import pickle
+from tqdm import tqdm
+from waymo_open_dataset.protos import scenario_pb2
+
+
+# from waymax import dataloader
+# from waymax.config import DataFormat
+import functools
+
+MAX_NUM_OBJECTS = 64
+MAX_POLYLINES = 256
+MAX_TRAFFIC_LIGHTS = 16
+CURRENT_INDEX = 10
+NUM_POINTS_POLYLINE = 30
+
+def tf_preprocess(serialized: bytes) -> dict[str, tf.Tensor]:
+ """
+ Preprocesses the serialized data.
+
+ Args:
+ serialized (bytes): The serialized data.
+
+ Returns:
+ dict[str, tf.Tensor]: The preprocessed data.
+ """
+ womd_features = dataloader.womd_utils.get_features_description(
+ include_sdc_paths=False,
+ max_num_rg_points=30000,
+ num_paths=None,
+ num_points_per_path=None,
+ )
+ womd_features['scenario/id'] = tf.io.FixedLenFeature([1], tf.string)
+
+ deserialized = tf.io.parse_example(serialized, womd_features)
+ parsed_id = deserialized.pop('scenario/id')
+ deserialized['scenario/id'] = tf.io.decode_raw(parsed_id, tf.uint8)
+ return dataloader.preprocess_womd_example(
+ deserialized,
+ aggregate_timesteps=True,
+ max_num_objects=None,
+ )
+
+def tf_postprocess(example: dict[str, tf.Tensor]):
+ """
+ Postprocesses the example.
+
+ Args:
+ example (dict[str, tf.Tensor]): The example to be postprocessed.
+
+ Returns:
+ tuple: A tuple containing the scenario ID and the postprocessed scenario.
+ """
+ scenario = dataloader.simulator_state_from_womd_dict(example)
+ scenario_id = example['scenario/id']
+ return scenario_id, scenario
+
+def data_process(
+ data_dir: str,
+ save_dir: str,
+):
+ """
+ Process the Waymax dataset and save the processed data.
+
+ Args:
+ data_dir (str): Directory path of the Waymax dataset.
+ save_dir (str): Directory path to save the processed data.
+ """
+ dataset = tf.data.TFRecordDataset(
+ data_dir, compression_type=""
+ )
+
+ os.makedirs(save_dir, exist_ok=True)
+
+ for tf_data in dataset:
+ tf_data = tf_data.numpy()
+ scenario = scenario_pb2.Scenario()
+ scenario.ParseFromString(bytes(tf_data))
+ scenario_id = scenario.scenario_id
+
+ scenario_filename = os.path.join(save_dir, scenario_id+'.tfrecords')
+
+ # check if file exists
+ if os.path.exists(scenario_filename):
+ continue
+
+ # Remove the .as_posix() method call since scenario_filename is a string
+ with tf.io.TFRecordWriter(scenario_filename) as file_writer:
+ file_writer.write(tf_data)
+
+
+if __name__ == '__main__':
+ # add arguments
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--data_dir', type=str, default='/data/Dataset/Waymo/V1_2_tf')
+ parser.add_argument('--save_dir', type=str, default='/data/Dataset/Waymo/VBD')
+ parser.add_argument('--dataset', type=str, default='all')
+ parser.add_argument('--num_workers', type=int, default=1) # Change default to 1
+ args = parser.parse_args()
+
+ os.makedirs(args.save_dir, exist_ok=True)
+
+ print(f'Processing data from {args.data_dir} and Saving to {args.save_dir}')
+
+ def process(dataset):
+ """
+ Process a specific dataset and save the processed data.
+
+ Args:
+ dataset (str): Name of the dataset to process.
+ """
+ data_path = os.path.join(args.data_dir, dataset+'/*')
+ data_files = glob.glob(data_path)
+ save_dir = os.path.join(args.save_dir, dataset+'_extracted')
+ n_files = len(data_files)
+ print(f'Processing {n_files} files in {data_path} dataset')
+ os.makedirs(save_dir, exist_ok=True)
+ print(f'Saving to {save_dir}')
+
+ # Process files one by one instead of using multiprocessing
+ for data_file in tqdm(data_files):
+ data_process(data_file, save_dir)
+
+ if args.dataset == 'all' or args.dataset == 'train':
+ process('training')
+
+ if args.dataset == 'all' or args.dataset == 'val':
+ process('validation')
+
+ if args.dataset == 'all' or args.dataset == 'val_interactive':
+ process('validation_interactive')
\ No newline at end of file
diff --git a/examples/eval/notebooks/wosac_results.ipynb b/examples/eval/notebooks/wosac_results.ipynb
new file mode 100644
index 000000000..e76e80422
--- /dev/null
+++ b/examples/eval/notebooks/wosac_results.ipynb
@@ -0,0 +1,312 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "import os\n",
+ "import glob\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def display_wosac_table(data_dir):\n",
+ " csv_files = glob.glob(os.path.join(data_dir, \"*.csv\"))\n",
+ " \n",
+ " if not csv_files:\n",
+ " raise FileNotFoundError(f\"No CSV files found in {data_dir}\")\n",
+ " \n",
+ " most_recent_file = max(csv_files, key=os.path.getctime)\n",
+ " print(f\"Using file: {most_recent_file}\")\n",
+ " \n",
+ " df = pd.read_csv(most_recent_file)\n",
+ " df = df.set_index(\"AGENT POLICY\")\n",
+ " \n",
+ " def highlight_best(df):\n",
+ " styles = pd.DataFrame('', index=df.index, columns=df.columns)\n",
+ " \n",
+ " higher_better_cols = [col for col in df.columns if '(↑)' in col]\n",
+ " lower_better_cols = [col for col in df.columns if '(↓)' in col]\n",
+ " \n",
+ " for col in higher_better_cols:\n",
+ " max_val = df[col].max()\n",
+ " max_indices = df[col] == max_val\n",
+ " styles.loc[max_indices, col] = 'background-color: #a8f0a8'\n",
+ " \n",
+ " for col in lower_better_cols:\n",
+ " min_val = df[col].min()\n",
+ " min_indices = df[col] == min_val\n",
+ " styles.loc[min_indices, col] = 'background-color: #a8f0a8'\n",
+ " \n",
+ " return styles\n",
+ " \n",
+ " styled_df = df.style.apply(highlight_best, axis=None).format(precision=3)\n",
+ " \n",
+ " return styled_df\n",
+ "\n",
+ "def create_radar_chart(data_dir='examples/eval/figures_data'):\n",
+ " csv_files = glob.glob(os.path.join(data_dir, \"*.csv\"))\n",
+ " \n",
+ " if not csv_files:\n",
+ " raise FileNotFoundError(f\"No CSV files found in {data_dir}\")\n",
+ " \n",
+ " most_recent_file = max(csv_files, key=os.path.getctime)\n",
+ " df = pd.read_csv(most_recent_file)\n",
+ " df = df.set_index(\"AGENT POLICY\")\n",
+ " \n",
+ " key_metrics = [\n",
+ " \"COMPOSITE METRIC (↑)\", \n",
+ " \"LINEAR SPEED (↑)\", \n",
+ " \"ANG. SPEED (↑)\",\n",
+ " \"COLLISION (↑)\",\n",
+ " \"TTC (↑)\", \n",
+ " \"OFFROAD (↑)\"\n",
+ " ]\n",
+ " \n",
+ " radar_df = df[key_metrics].copy()\n",
+ " for col in radar_df.columns:\n",
+ " if '(↑)' in col:\n",
+ " radar_df[col] = (radar_df[col] - radar_df[col].min()) / (radar_df[col].max() - radar_df[col].min())\n",
+ " else:\n",
+ " radar_df[col] = 1 - ((radar_df[col] - radar_df[col].min()) / (radar_df[col].max() - radar_df[col].min()))\n",
+ " \n",
+ " categories = [col.replace(' (↑)', '').replace(' (↓)', '') for col in key_metrics]\n",
+ " N = len(categories)\n",
+ " \n",
+ " fig = plt.figure(figsize=(6, 5))\n",
+ " ax = plt.subplot(111, polar=True)\n",
+ " \n",
+ " angles = [n / float(N) * 2 * np.pi for n in range(N)]\n",
+ " angles += angles[:1]\n",
+ " \n",
+ " top_policies = df.sort_values(\"COMPOSITE METRIC (↑)\", ascending=False).head(5).index\n",
+ " \n",
+ " colors = plt.cm.tab10(np.linspace(0, 1, len(top_policies)))\n",
+ " \n",
+ " for i, policy in enumerate(top_policies):\n",
+ " values = radar_df.loc[policy].values.flatten().tolist()\n",
+ " values += values[:1]\n",
+ " \n",
+ " ax.plot(angles, values, 'o-', linewidth=2, color=colors[i], label=policy)\n",
+ " ax.fill(angles, values, alpha=0.1, color=colors[i])\n",
+ " \n",
+ " plt.xticks(angles[:-1], categories, size=12)\n",
+ " \n",
+ " ax.set_rlabel_position(0)\n",
+ " plt.yticks([0.25, 0.5, 0.75], [\"0.25\", \"0.5\", \"0.75\"], color=\"grey\", size=10)\n",
+ " plt.ylim(0, 1)\n",
+ " \n",
+ " plt.legend(loc='upper right', bbox_to_anchor=(0.1, 0.1))\n",
+ " plt.title('Key Metrics Comparison (Normalized)', size=15, y=1.1)\n",
+ " \n",
+ " return fig"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Using file: ../figures_data/wosac_table_2025-04-24 09.csv\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | | \n",
+ " REPLAN RATE (Hz) | \n",
+ " LINEAR SPEED (↑) | \n",
+ " LINEAR ACCEL. (↑) | \n",
+ " ANG. SPEED (↑) | \n",
+ " ANG. ACCEL. (↑) | \n",
+ " DIST. TO OBJ. (↑) | \n",
+ " COLLISION (↑) | \n",
+ " TTC (↑) | \n",
+ " DIST. TO ROAD EDGE (↑) | \n",
+ " OFFROAD (↑) | \n",
+ " COMPOSITE METRIC (↑) | \n",
+ " ADE (↓) | \n",
+ " MINADE (↓) | \n",
+ " COLLISION RATE (↓) | \n",
+ " OFFROAD RATE (↓) | \n",
+ "
\n",
+ " \n",
+ " | AGENT POLICY | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | Logged oracle | \n",
+ " - | \n",
+ " 0.476 | \n",
+ " 0.478 | \n",
+ " 0.578 | \n",
+ " 0.694 | \n",
+ " 0.476 | \n",
+ " 1.000 | \n",
+ " 0.883 | \n",
+ " 0.715 | \n",
+ " 1.000 | \n",
+ " 0.819 | \n",
+ " 0.000 | \n",
+ " 0.000 | \n",
+ " 0.028 | \n",
+ " 0.111 | \n",
+ "
\n",
+ " \n",
+ " | Guided self-play (ours) | \n",
+ " 10 | \n",
+ " 0.589 | \n",
+ " 0.366 | \n",
+ " 0.629 | \n",
+ " 0.446 | \n",
+ " 0.376 | \n",
+ " 0.999 | \n",
+ " 0.989 | \n",
+ " 0.531 | \n",
+ " 0.999 | \n",
+ " 0.791 | \n",
+ " 0.873 | \n",
+ " 0.873 | \n",
+ " 0.000 | \n",
+ " 0.000 | \n",
+ "
\n",
+ " \n",
+ " | VBD | \n",
+ " 0.125 | \n",
+ " 0.359 | \n",
+ " 0.366 | \n",
+ " 0.420 | \n",
+ " 0.522 | \n",
+ " 0.368 | \n",
+ " 0.934 | \n",
+ " 0.815 | \n",
+ " 0.651 | \n",
+ " 0.879 | \n",
+ " 0.720 | \n",
+ " 2.257 | \n",
+ " 1.474 | \n",
+ " 0.036 | \n",
+ " 0.152 | \n",
+ "
\n",
+ " \n",
+ " | Random agent | \n",
+ " 10 | \n",
+ " 0.002 | \n",
+ " 0.116 | \n",
+ " 0.014 | \n",
+ " 0.034 | \n",
+ " 0.000 | \n",
+ " 0.000 | \n",
+ " 0.735 | \n",
+ " 0.148 | \n",
+ " 0.191 | \n",
+ " 0.144 | \n",
+ " 50.739 | \n",
+ " 50.706 | \n",
+ " 1.000 | \n",
+ " 0.613 | \n",
+ "
\n",
+ " \n",
+ "
\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "table = display_wosac_table(data_dir=\"../figures_data\")\n",
+ "display(table);"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAqsAAAIMCAYAAADSAuWnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd3hb1fnA8e/VtuSl4b0z7CwCBAgrkEDYe++wV4Hwo9BCoEAppWWPNkBZLavMQguEGfYqBMpKCIQkjndsS7IsW3vd+/tDthLH25ZsJzmf58kDV7rjSNZ4dc573iMpiqIgCIIgCIIgCBOQarwbIAiCIAiCIAj9EcGqIAiCIAiCMGGJYFUQBEEQBEGYsESwKgiCIAiCIExYIlgVBEEQBEEQJiwRrAqCIAiCIAgTlghWBUEQBEEQhAlLBKuCIAiCIAjChCWCVUEQBEEQBGHCEsGqsE2rqqqiqqqqz/ui0ShXXHEFVVVVHHjggTQ3N49x63pbunRpos3nnXfegPsefvjhiX3//e9/j1ELB1ZVVcX+++8/3s3oob29nfvvv5+TTz6ZPfbYg5kzZ7L77rtzxhln8Oijj+Jyuca7iRPaRPybjtTXX39NVVUVzzzzTI/blyxZMuh7yeFwbFPPxWAaGxupqqpi0aJFPW5fsWIFVVVVLFmyZJxa1lt/bX3iiSeoqqpi5cqV49QyIVlEsCpsl6LRKFdeeSVvvfUW5eXl/POf/6SgoGC8m9XDF198gdPp7PO+1atXs379+qReb//99+83sN9avffeexxwwAEsXbqUDRs2MHPmTA455BBmzZrFzz//zF133cWBBx7IunXrxrupQoopisLtt99Ofn4+J554Yr/7Pfjgg0Sj0TFsmZAqp5xyCjabjdtvv328myKMkma8GyAIYy0SiXDllVeyfPlyKioqePLJJ8nLyxvvZvUwY8YMfvrpJ15//XXOPvvsXve/9tprAMycOZPVq1ePcev69+abb6LVase7GQB8/PHHLF68GJVKxZIlSzjjjDN6tC0cDvPaa69x7733it7VAUykv+lovPfee6xatYprr70WnU7X5z4Gg4GGhgb+85//DBjQbs9mz57Nm2++SUZGxng3ZVAGg4GzzjqLu+++m48//pj58+ePd5OEERI9q8J2JRKJcMUVV7B8+XImT57M008/PeECVYD58+eTmZnJsmXLet0Xi8V44403qKioYNasWePQuv5NnjyZ0tLS8W4Gfr+fJUuWIMsyt9xyC+ecc06vgEun03HCCSfw73//m6KionFq6cQ3Uf6mo/Xss8+iVqs54ogj+t3nlFNOAeBvf/sbkUhkrJq2VUlLS2Py5Mnk5uaOd1OG5Mgjj0SSJJ577rnxboowCiJYFbYb4XCY//u//+O9995j6tSpPP300+Tk5PS57yeffMKFF17IHnvswaxZs1i4cCG33nor7e3tPfa76KKLqKqq4rPPPuvzPIFAgF133ZWdd94Zr9c75LbqdDoOPvhgfvzxRzZs2NDjvi+++AKHw8GRRx454Dmi0SjPPvssJ598MnPmzGH27NkcffTRPPHEEz2GObtz0JqamoBNeb5b5uctWrSIqqoqGhsbWbZsGSeddBI777wzu+66a2KfgXL6qqurue6669h///2ZNWsWe+65J6eccgp///vfe7TH5/Px8MMPc9RRR7HLLruw8847c8ABB3D55Zfz6aefDun5e+WVV3C5XOy4444ce+yxA+6bl5dHcXFxj9va29u5/fbbOeigg9hhhx2YO3cu5513Xr9/5+7HHY1GeeCBBzjwwAOZPXs2hx56KC+//HJivy+++IJFixYxZ84cdtttN66++uperyno+Vy/+uqrHHfccey4447sueeeXHPNNbS2tvY6prOzk6effprzzjuP/fbbj1mzZrH77rtz3nnn8fnnn/fZ7tH8Tb/99lsuueSSxLX23ntvTjjhBO666y58Pl+v/V955RVOPfVU5syZw4477siRRx7Jww8/TCgU6rVvdw7pihUr+PrrrznzzDPZeeedmTNnDhdeeOGwU2AaGhr44osv2GOPPbDZbP3uN2PGDBYuXEhTU1OPv9tQfPzxx5xzzjnstttu7LDDDhx88MHcdddddHZ29tq3Ozf93//+NytXruSiiy5i9913p6qqip9//rlHXmhbWxvXXXcde++9NzvttBOnnnoq3377beJczz33HEceeSSzZ89m/vz5LF26FFmWe13zf//7HzfffDNHHnkku+22G7Nnz+aQQw7pt4396Stntfu2gf5tmeOqKAqvv/46Z555ZuI5O/TQQ1m6dCmBQKDPazc3N/Pb3/6WPfbYgx133JHjjjuOV199dcD2FhQUsMsuu/DJJ5/0+b4Rtg4iWBW2C+FwmMsvv5z333+fqqoqnnrqKaxWa5/73nXXXVxwwQX897//paKigv333x+NRsMTTzzBSSed1COP9OSTTwbgxRdf7PNcb7/9Nh6Ph8MPP5z09PRhtbk7GN2yd7V7+6ijjur32GAwyLnnnssf/vAHamtr2Wmnndhrr71wOBzceuutLF68OPGFZrPZOPbYYzEajQAce+yxiX8HH3xwr3M/8sgjXH311Wi1Wvbbbz+mTp066GN56623OOaYY3j55ZcxGAwceOCBzJw5k5aWFu644w78fj8Q7zU+55xzuOeee7Db7cydO5f58+djs9n45JNPeOONN4bwzMUDB2DAXrT+tLa2cuKJJ/KPf/yDSCTCAQccwPTp0/niiy8477zzeOKJJ/o99oorruDxxx+nsrKS3XbbjcbGRq677jpefvll3n77bc4//3xisRjz5s0jLS2NV199lUsvvRRFUfo83z/+8Q+uueYajEYjCxcuJC0tjVdeeYWTTjqJlpaWHvt+//333HLLLdTU1FBRUcGBBx5IRUUFn3/+Oeeddx4vvfRSv+0e7t/0gw8+4PTTT+eDDz4gJyeHgw46iOnTp9PR0cGjjz7aKwC/8cYbueaaa1i9ejW77ror8+fPx+FwcM8993DWWWf1G5x8+OGHnHXWWQSDQebPn09OTg4ff/wxp59+Og6HY8A2bu6TTz5BURTmzp076L6XX345kiTx8MMPEw6Hh3T+hx9+mAsvvJCvvvqKmTNncsABBxAMBnn00Uc58cQT+809//rrrznttNNoampi7733ZrfddkOSpMT9HR0dnHzyyXz55ZfMnTuXyspKvv32W84991zWrVvHLbfcwm233UZBQQF77bUXHo+H+++/n7/85S+9rnXHHXfw0ksvYTAY2HPPPdlzzz3xer08+uijnHbaaX3+wBiq7s+Qvv5198qrVJvCDVmW+c1vfsNVV13FqlWrmDZtGvPnzycQCHD//fdz5plnEgwGe1yjoaGBE088kddee4309PTE++Gaa67h8ccfH7B9c+fOJRaLDfnHrjABKYKwDausrFQqKyuVCy+8UKmsrFSOPvpoxeVy9bv/m2++qVRWVipHHHGEUltbm7hdlmXlL3/5i1JZWalcccUViduj0agyf/58ZebMmYrT6ex1vlNOOUWprKxUfvjhhyG1969//atSWVmpPPDAA4osy8r8+fOVhQsXJu4PBALKzjvvrJx88smKoijKDTfcoFRWViovv/xyj/PcdNNNibZ2dnYmbvd4PMoFF1ygVFZWKs8++2yPY/bbbz+lsrKy37adccYZSmVlpbLDDjsoK1as6HOfyspKZb/99utxW01NjbLDDjsoM2bMUF577bUe98myrHz66adKKBRSFEVRvvjiC6WyslI5/vjjlWAw2GNfj8ejrFq1qt/2bW6fffZRKisrla+//npI+2/uoosuUiorK5Urr7wy0S5FUZSvv/5a2XHHHZXp06crP/30U49jul9nRxxxhNLW1pa4vfvx7L333srcuXOVDz/8sMfjOfzww5XKykrliy++6HG+7ud6xowZykcffZS4PRwOK1dddZVSWVmp/OpXv+pxTH19vfLdd9/1ejyrV69Wdt11V2XOnDmK1+vt8zrD/ZuefvrpSmVlpfL222/32v+HH35QPB5PYvvtt99WKisrlXnz5ik1NTWJ2zs7O5VTTz1VqaysVG677bYe57jmmmuUyspKZdq0acq7776buD0ajSqLFy9WKisrlfvuu6/P9vbliiuuUCorK5XPPvusz/u7r/fKK68oiqIol112mVJZWan885//TOxjt9v7fC5++OEHZdq0acpOO+2kfP/994nbQ6GQcvnllyuVlZXK4sWLexzT/T6vrKxUHnnkkV7t+fLLLxP3/+Y3v1HC4XCvYw877DBl3rx5Sl1dXeK+devWKTNnzlR23HHHXn/rjz76qMdnQXcbuz9Dli5d2uO+hoYGpbKyUjnjjDP6bNs111zT+4ncwnfffafMmjVL2XXXXZUNGzYkbn/00UcT57bb7T3ac9111ymVlZXKnXfe2eNc5513nlJZWalce+21SiQSSdz+/vvvK9OnT++zrd0++OADpbKyUrn66qsHbbMwMYmeVWG78NFHHyFJEnfccQdms7nf/R566CEA7r77bsrKyhK3S5LE4sWLmT59Ou+8805iQo5arebEE08kEonwn//8p8e5qqur+fbbb6mqqmL27NnDbrMkSRx++OE0NDTw3XffAfFJIj6fb8AUgLa2Nv71r39RUFDArbfe2mMiRHp6On/605/QarUjzuE64YQThtRD1e2JJ54gFApxwgkn9Gq3JEnMmzcvMeGl+3mdM2cOer2+x77p6elDztF1u90AWCyWIbcT4r03H374IUajkRtuuKHHRJxdd92VU045hVgs1qv0UbfrrruuxzX32GMPZsyYgcPhYN9992XBggU9Hs9JJ50ExHvY+nLIIYf0mBSi1Wr53e9+R1paGh988EGPcmslJSXstNNOvc4xY8YMTjvtNLxeLytWrOjzOsP9m3b/nfbaa69e982ePbvHKMLTTz8NwGWXXUZ5eXni9oyMDG688UYkSeL555/vMx3g8MMP54ADDkhsq9VqLrzwQiA+rD1Uv/zyCwAVFRVD2v+yyy4bcu/qM888gyzLLFq0iB133DFxu06n48Ybb8RgMPDuu+/2WRqvsrKS888/v99zp6enc/311/fItz777LORJIn169dz+eWX98gnnjJlCgsWLCAQCPDjjz/2ONf8+fN7TYrS6XRcd911aDQaPvjggwEf53C1tLRw2WWXEYvFuPfeexPPfTQa5bHHHsNoNHLvvff2SMXS6XTccMMN5OTk8OKLLyZGfxoaGvj0009JT0/n2muvRaPZNDd8//3373MEaHOTJk0C4Oeff07qYxTGjghWhe3CnDlzUBSFX//61/3O/G5ra2PNmjWUl5dTWVnZ635JkpgzZw6xWKzHDPwTTzwRjUbDv/71rx77d293pwqMRPdQf/fs/9deew2tVsthhx3W7zErVqwgEomwzz77YDAYet2fk5NDeXk5a9eu7TXUNhTDrTP5xRdfAJsmrwxk+vTpqFQq/v3vf/Piiy/2mc+ZSt988w0A++yzD9nZ2b3uP/roo4G+AyWtVttnwFdSUgLA3nvv3e99/Q1pH3744b1uM5vN7L333iiKkmhvt1gsxmeffcbSpUu58cYbWbJkCUuWLEkEqXV1dX1eZ7h/05kzZwLw29/+lpUrV/aZIwnxCY3ff/89QJ8/sKZNm0ZVVRV+v7/PQGLevHm9busOeO12+5Db29bWBkBmZuaQ9q+qquLggw+mtbWVF154YcB9u18LfT0+q9XK3nvvjSzLPfJMu+233349hv23NGvWLLKysnrclpGRkbitr+dnoNdUa2srzz33HH/605+49tprWbJkCTfddBNarZba2tr+H+QwBYNBLrnkEhwOB9dcc02Pdv7000+0t7ez884795k/bDAYmDlzJh0dHYk2bf6+7KsKQV/vk811P1+i6sfWS5SuErYLjzzyCGeddRarV6/m/PPP56mnnuqVQ9o9wai2tnbQeqObB1G5ubnsv//+LF++nK+++oq5c+cSDod55ZVXMBgMg06EGkj35IS33nqLiy++mM8//5x99tlnwN7h7sfx4osv9ptL262jo6PPgHYgw61H292j1P0lOpCKigp++9vfcs8993DDDTfw+9//nqlTp7Lnnnty7LHHMm3atCFdMzs7m9bWVlwuV6JXZSi6A6D+qgN0397XRA2bzYZare51e3cucF9VJ7rv66/3rrCwcMB2bB6wtbS0cNFFF7FmzZo+jwH6zUsc7t/0yiuvZO3atXz44Yd8+OGHZGVlMWfOHBYuXMhRRx2V6BV3u91EIhHMZnPisfb1WNasWdPnc9rXc9b9vh3ObP3uyY0mk2nIx1x22WUsX76chx9+ONED3pfRvGYGe977q1RiMplwu93Dek09/vjj3H333WNS5WDJkiWsXr2aE044gbPOOqvHfY2NjQB8/vnnQ/6c7X6O+3s/bDlBckvdrxmPxzN444UJSQSrwnYhIyODxx57jEWLFrF69WouvPBC/v73v5OWlpbYp7t3KCcnp88ei81t+aF5yimnsHz5cl588UXmzp3Le++9R3t7O8ccc8yQe3P6c+SRR3LXXXfxu9/9jmg0OuDEKiAxWWf69OmDBncjqZ+55fB8sp177rkceuihvPfee3z++ed88803PPHEEzz55JNce+21vb78+jJ9+nRaW1v56aefesxsH62BesE2n0AykvtH63e/+x1r1qzh4IMP5vzzz6eiogKTyYRKpeKFF17gxhtv7Hci13D/pgUFBbz88st8+eWXfPTRR3z11VeJwPWxxx7j+eefH/AH1eZG85wOVXp6Om63G5/PN+SJjlOnTuWQQw7hzTff5Lnnnhu0964/Az2+wZ73ZL2mvv/+e2677TYyMjL44x//yNy5c8nJyUmkucybN29YE9YG8sADD/DWW2+xyy678Pvf/77X/d2vwbKyMubMmTPgufoa3RiJ7iB1a6gNK/RNBKvCdsNisfD4449z+umn880333DZZZfxt7/9LfGBnZ+fD8SHWW+77bZhnXuvvfairKyM5cuX09HRkUgBGKhHZqiOPPJI7r777kTO1sKFCwfcv7u3ZZddduGGG24Y9fVHq6CggNraWhoaGpg+ffqQj1m0aBGLFi0iGo3yxhtvcN1113HnnXdyzDHH9Boa3dL8+fP56KOPeOONNzjzzDOH3Nbu2pEbN27s8/7uXuuxqs27cePGPn9wdLevu71+v5///ve/2Gw27r333l49vA0NDUlvm0ajYd68eYkfdk1NTVx33XV8+eWXPProo1x99dVkZ2ej1Wppb2/H7/f32bs6Fs+p1WrF7XbT0dExrKocl112GW+//TaPPvpov++73NxcGhsb2bhxI1OmTOl1/1i/Zvry7rvvAvDrX/+6Vym3YDDYb7WCkVxn6dKlFBUVcf/99/e5+EL38zBp0qQhf85257UO9r7sT3dpruHmsAsTh8hZFbYrubm5PP744+Tn5/PZZ59x5ZVXEovFgHiwOmnSJNavX09NTc2wzitJEieddBKhUIgHHniAL774gsmTJ7PLLruMus35+fksWLCA7OzsHkOs/dljjz1Qq9V8+OGHwxry6+5lTfZSk3vuuSfAoLl//dFoNBx99NHssMMORCKRfvMuN3fMMcdgsVj4/vvve01821Jra2tiaLL77/Xpp5/2WXuyu6ZjMntrB/LWW2/1us3tdvP5558ncqgh3nMkyzI5OTm9AtVIJJIIVlKpqKiICy64ACCxfK1Wq01M+uqr7NjatWtZs2YNRqNxyD9kRqI74B/u+3ry5MkcdthhOJ1Onn322T736X4tvP76673uc7lcfPbZZz3+VuOh+7XcV8D89ttv99vjPhxr1qzh6quvJi0tjQcffLDfwHD27NlkZGTw1VdfJSZCDmbz92Vf9arffPPNAY+vrq4GSOlrTEgtEawK253i4mIef/xxrFYr7777LkuWLEl8WF9yySXIsszll1/e54SP9vb2fvNAjzvuOHQ6HU8++SSKoiSlV7XbQw89xIoVK/ocVttSXl4exx9/PE1NTVx11VV99prU1dXxzjvv9Litu5duuF/ogznrrLPQ6/X861//6vWloigKn3/+eSK/7ssvv+S///1vrwk7DQ0NVFdXI0nSkHqojEYjt912GyqViuuvv54nnniiV+AejUZ55ZVXEs8VxPNqFyxYgM/n409/+lOPY7777juef/551Go1p59++oiei+F66623etSGjEaj3Hrrrfj9fhYsWJBIR7FarWRkZLBu3boek65isRh33XVXUifPQLzCQ1/Dxt31bTfPxTzjjDMAuP/++3v08Hq9Xv74xz+iKAqnnHJKStNLuoOdVatWDfvYSy+9FLVa3W+wevrpp6NSqXj66ad7nD8cDvPHP/6RYDDIQQcdNOy84GTqnpT20ksv9XhNr1+/nrvuumvU53e5XFxyySUEAgFuv/32AdOPdDod559/Pj6fj8WLF/fZ69/a2sorr7yS2C4tLWXevHl4vV5uu+22RAcDxF9zb7/99oDtW7lyJQC77bbbMB+ZMFGINABhuzRp0iT+8Y9/cOaZZ/Laa69hMpm46aabOPLII1m/fj0PPfQQxx13HNOnT6ekpARFUWhoaOCXX37BaDT2GYhaLBYOOuggXn/9dXQ6XWLm+Hj43e9+R1NTE++88w6ffvop06ZNo7CwEL/fT3V1NXV1dSxcuLBHyZf999+fr776irPPPpvdd9+dtLQ0zGYzv/nNb0bVloqKCm699VauueYafv3rX/PAAw9QVVWFx+Nh3bp1NDc38/XXX6PT6VizZg233norFouFmTNnkp2dTXt7O1999RXhcJhFixYNeTh1/vz5/PWvf+Waa67h1ltv5YEHHmDHHXckKysLt9vNypUr6ezsJDMzs8cCETfffDOnnXYar7zyCl9//TU77bQTLpeLr776ilgsxpIlS8ash+akk07iggsuYLfddiMnJ4cffviBxsZGcnNzufHGGxP7aTQazj//fO69914WLVrEHnvsQVZWFj/88ANtbW2cfvrp/ZbbGon7778/EZSUlZWhKApr1qyhtraW7Oxszj333MS+hxxyCCeffDIvvPACRxxxBHvssQcGg4GvvvoKl8vFTjvtxOWXX560tvVl3333RZIkvvrqK371q18N69hJkyZxxBFH9LtS0uzZs/m///s/7r33Xk455RTmzp2L2Wzm22+/pbm5mfLy8h5/q/Fw3HHH8fjjj/Phhx9yyCGHsMMOO9DR0cHXX3/NwoULWbVq1aBD6QN57rnnaGpqIicnhw8++KDPMli77LILJ554IgAXXnghGzZs4NVXX+XQQw9lxowZFBcXE4lEqKmpYf369VRVVXHMMcckjr/ppps45ZRT+Ne//sWKFSvYYYcdsNvt/O9//+O0004b8PX91VdfoVar2WeffUb8GIXxJYJVYbs1bdo0Hn30Uc4++2yee+45jEYjV199Nb/+9a+ZN28e//znP/n2229Zu3YtJpOJvLw8Tj31VA455JB+z7nHHnvw+uuvc9BBBw15gkkqGAwGHn30UZYtW8Z//vMf1qxZw6pVqzCbzRQVFXHUUUf1mjCyaNEiOjo6eOONN1i+fDmRSISioqJRB6sQLy0zefJk/v73v7NixQqWL19OZmYmZWVlnHXWWYlcxv322w+3282KFStYs2YNbrcbi8XCLrvswmmnncaBBx44rOseeOCB7LLLLjz77LN88sknrFq1Cq/XS3p6OlVVVey3334cf/zxPSZy5OXl8dJLL/HII4/w3nvvsXz5ctLS0thzzz0555xzBp18l0znnnsus2bN4qmnnuKHH34gLS2No48+miuvvDKRY93t4osvJj8/nyeffJJvv/0WvV7PLrvswuWXX85PP/2U1HZdf/31fPrpp6xevZpPPvkEiPemnnPOOZxzzjm9flDcfPPNzJkzh+effz4R9JeWlnLWWWdx9tlnD7sixXCVlJSw11578eWXX+JwOPpdZrk/l156Ka+//nqPHr3NXXzxxUybNo0nnniCVatWEQwGKSws5Pzzz+fCCy8cNMc61cxmMy+99BJ33nknX3/9NR988AHFxcVcfvnlnHfeecN+X22peyTE4XAMmHbTHayqVCruuOMODj74YF588UVWrVrFTz/9RGZmJvn5+Zx33nm9yvOVlJTw4osvcs899/DZZ5/x3nvvMWnSJG699VZ22223foPVjRs38u2337JgwYJxzRsWRkdSkpGsIggCQGL9+Keeeordd999vJsjbKUWLVrEV199xfvvvz9oWR5haN577z0uvfRSrrnmmh49v8K27eGHH+aee+7hkUce6bHAhrB1ETmrgpAkK1eu5PPPP2fq1KkiUBWECeaAAw5g9uzZPPHEE4OuSiVsG4LBIE8//TS77rqrCFS3ciJYFYRRuuuuu7jqqqs455xzUBSFK664YrybJAhCH66++mpaW1sHXSxD2DY8//zziVW0hK2bSAMQhFHaf//9aW5uprCwkHPPPXfMZooL2y6RBiAIgrCJCFYFQRAEQRCECUukAQiCIAiCIAgTlghWBUEQBEEQhAlLBKuCIAiCIAjChCWCVUEQBEEQBGHCEsGqIAiCIAiCMGGJYFUQBEEQBEGYsESwKgiCIAiCIExYIlgVBEEQBEEQJiwRrAqCIAiCIAgTlghWBUEQBEEQhAlLBKuCIAiCIAjChCWCVUEQBEEQBGHCEsGqIAiCIAiCMGGJYFUQBEEQBEGYsESwKgiCIAiCIExYIlgVBEEQBEEQJiwRrAqCIAiCIAgTlghWBUEQBEEQhAlLBKuC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7Ljjjj0CU5PJJALTYeoOYG02G6WlpYkAtrS0FK1Wi8PhYNWqVRQWFnLBBRcQi8VGFLymp6dz1llnJXpXBxOLxfp8bfn9/l77Dvf9uzmPx0NnZydZWVmD7rs9vOcEoT8iDUAQxtGPP/7Ihg0buOGGGwDYZZddyM/PZ9myZcyePbvPY3bddVd23333RO5qX/mDdXV1RKNRpk6d2us+t9uNLMuJ7ZEMux5//PE88cQTLFmyhEceeYS5c+ey2267MX/+/H7z+lwuFxAfsnzrrbd47733qKqqYtKkST32O+SQQ3od29fElqVLl/bZU/bCCy/02fvUl8rKSiDea6UoCoFAALfbTUdHB36/n7S0NDIyMigsLCQjIwONRnxkppparSYrKysRwMViMd555x08Hg+yLLNq1apE7m92djYmk2lIOa9nnnkmTz75JPfff/+g6S8bNmxgzz337HX7ySefzM0335zYHu77NxQKJd4HGzdu5L777iMWi3HwwQcP2v5t8T0nCEMlPnkFYRwtW7YMm83G7rvvDsRz/g477DBee+01lixZ0u8Q/eLFiznjjDN4/vnnOfvss3vd7/V6AfqcNHHAAQf0GIL7y1/+0ueX1UBsNhuvvvoqDzzwAO+99x7PP/88zz//PFqtll/96ldccsklPQIIv9/f68t/55135s477+x17qVLl/ZKW+hrMtnJJ5/cZ7unTJky5MdhNBrZcccdsdlsrFq1ilgsRmZmJrm5uWRmZopJIBOAWq0mGAzy/PPPc8IJJzBjxgw6Oztxu92sX78eSZLIzMwkFov1O/EL4nmUZ555JkuXLuWnn37qNSloc0VFRYnJSZvbPM8Thv/+femll3jppZcS21qtlvPPP3/Q/HPYtt5zAD6fb8jHCIIIVgVhnMRiMd544w123313GhsbE7fPnj2bf/zjH3zxxRfMmzevz2N32203dt99dx577DFOOeWUXvd3f/H0NWz54IMPEo1GWbNmDbfffvuI25+bm8sf/vAHbrrpJmpra/nss8949NFH+etf/0pubi4nnnhiYl+9Xp+Yia3T6SguLu43PWHXXXcd0mSPsrIy9tprr2G3OxqN0tHRgdvtRqfTce6556JSqSgvLxc5plsBtVqN2WzGbDajKAo+ny/RG/7www8TCASw2+29hroBzjrrLJ588kmWLl06YO+q0Wgc9LU1kvfvwoULOeOMM4hEIqxatYqHHnqIYDA45Nfc1vqe21z3Z9LmlQsEYTAiWBWEcfLll1/icDh44403eOONN3rdv2zZsn6DVYDLLruMRYsW8fzzz/cqMVNaWopGo2HdunW9juueZDGSiVV9kSSJiooKKioqWLBgAQcddBCvvfZajy9OtVo96i+50ZBlOZGX19HRQVpaGtnZ2Xz66afceuutPPLII72eQ2HikySJ9PT0xI+z008/nauuuor29nYaGhpQqVTsu+++iR7HjIwMzjrrrETv6miM5P2bn5+feB/Mnz8fs9nMzTffzO67785BBx005GtvDe+5/qxduxZgwPJ8grAlEawKwjhZtmwZVquVG2+8sdd97777Lu+++y5/+MMf+h3anDt3LnPnzuWxxx7jkksu6XGf0Whk7ty5fP3117S2tvYavkyVkpISMjMzcTgcY3K9gSiKQnFxMfvssw8rV65Eo9FgsVgoKirCYDAQi8V48cUXSUtLY5dddhnv5gpJ0NLSgsPh4KijjiIcDvP9999zyCGHYLVa2bBhAxaLpUfu6mh+oIz2/QvxYfUnnniC++67jwMPPHBE9WYn0ntuMLFYjNdff12854RhE+NdgjAOgsEgy5cvZ8GCBRxyyCG9/p1++un4fD4++OCDAc+zePFiHA4HL774Yq/7Lr30UmKxGL/5zW/6zA/ra/E6l8tFdXU1gUBgwOv+8MMPfaYYrFy5ErfbTUVFxYDHp1IgEKCxsZFVq1Zx2GGHEYlEmDp1KjNnzqSwsDARqN5yyy1UV1ezaNGiPkt7CVs3nU6Hoihcd911tLe3o9fraWhoYMOGDdx0003U19fz888/j+jcyXr/ajQazjnnHKqrq3n//fcH3Hciv+eGQrznhNEQPauCMA4++OADfD4f+++/f5/377TTTlgsFl577TUOO+ywfs/T3bva1/KQu+66KzfccAO33HILBx98cGIFq3A4TG1tLcuWLUOr1WKz2RLHPPPMM9x///089dRTiUkjfXn11VdZtmwZBxxwALNmzUKr1VJdXc3LL7+MXq/n4osvHsaz0dM777zT58Swvffeu0dbf/rpp0QZH0mSSEtLS1Q2sFgslJWVcfnll1NbW0txcTEQDzK6V9Opr6/n8MMP5//+7/9G3FZhbL388st8+umnvW7vXlK1P7FYjKKiIgoLC/F6vZhMJq6++mo6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t4x4LqFwmD/+4Q/46+r4xte/htfrLT934okn0NPTw5tvvV1+7M4772TVqlWcetppHDZ9Oh6Ph2XLHmHu3LnMnz+Pf/zj/7jzn//EYXeU59+diXB339Oc5z0Wn8UNsQLqA920L0xSKBRZsWIFhxxyCC+++MJO53jEEUdgMBhYtXoV5513PrlcnpdeepFVq1axYMF8eoTCywYTx6tZrFLy0WIex9lncTbw04fe5Z63ulGBq299jfs+dzTzGly88847uN1u7r77btzubVO+dnftOPDAA7eJIr7zzjvccMMNHHDAAZxzzs7dGVwu1y6fGw7HHXccjz32GCtXrmTBggXlx5944gny+TxHH300L7/88ojH3f65t956i+eff36nr+no6ABg0aJF2zx/8MEHc+WVV3L77bfzn//5n7t9H4888gi/+93vOPXUU/nFL36xzSrsZz7zGZYvXz6iRg16zupexk033UQqleK///u/txGqA0yfPp3LL7+crq4u7r77bg4//PBthOoAl1xyCYcddhh33303XV1d4zF1Nm/ezL777ruDUAWoq9u5RyFoYql95VrODvVjklqe6b8Xn8jlp+wHaFWo11xzDXaHkzvuuBOpSuTWDOaOAov9c7j4oA/zpQM+MShUp9sQx9ShitrtrDOeFIpFBNR0GkOxmK+pnGGHw4HFYiYSiRDKZjkrEueo3jhnRGL0SbnTiOtkxWA0UigWyh26Fi5cwNq161i3bj2xWIxXXn6ZYrHA7NmzAXj++RdYUWqfDNrS/5tvvcURRxyBw+Egnc6QTmfIly6U+UKB119/g3C4l0QiSWdnF8888wwup5Pm5qbtpzMqhnqtjnT+b739Dlu3dtKfSNLbG+H5F54nkUgyd+6cEc9j2bJlZLNZPnnFFdsI1QHq6+s55eQPARCJ9PHs8udYsGAhgbpguUvVwPynT5/O4sX70N3VRT6fL8+/ra0V6VR4XL5JXz6uHbi/QMNrAr/JjdVs5axZx/OpRefjblfIpbO8+OJLFApFbDYbXV3dPProo3jcblpbW8tpYD2l5i3/uu8+/oWCWhI/2bvuIPWH35P82U+4LvomB/q180wyp/LJv73Klr40WzJGAsH6HYQq7P7aMREccMABtLa28sADD2zz+AMPPMDRRx+9089tvDjkkEMALei1J37zm9/g9Xr58Y9/vNPukccccwwn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cGkKE/p3PW3go48+IiwsjCeffBJJkkhMTKSkpISXX36ZuXPnotfrWb9+PS+//DIXXHABAM899xwjR460HyMjI4Pt27ezevVq+vfvD8DixYu59NJL7W127drFn3/+ya+//mo/Bf/II4+wdetWvv76a6677jpWrVrFlClTmDp1KgDz5s3j119/bXN2tb3xN51WjYuL4+GHH3a470033WT/OSoqivvvv5+nnnqKRYsWAbBs2TL69etnvwzQq1evFsdRWFjI2rVr+f777wkNDQVg9uzZ/Pzzz6xdu5b58+e3+hgEoWkRVkBAAOXl5eTm5qJUKgkLCyMwMFC86Qs9TtNManFxMQaDgZCQEJKSks7YDT8EoSfoUrC69KcMMsrq22/YAY0BbetBbZO3f8p0SrCakZHBOeec4/BmeO6556LX6ykuLkan02E2mxkwYID9dl9fX+Lj4+2Xs7KycHNzo2/fvvbrYmNj8ff3t19OS0tDr9czdOhQh/4NBgO5ubn2sUybNs3h9kGDBrV5Kr298UdERAA4jK3J9u3befvtt8nMzKSurg6r1YrRaKShoQG1Ws3BgwcZP358q30f7/Dhw1it1mbtTSaTfU9sQWiPQqEgJCSE4OBgKioqKCoqorCwkNDQUIKDg0VOq3DKNeWkFhcXY7FYCA0NRavViiBVELpBl4LV2y9K5P+2dG1mtUmAl6pDM6u3X5jQ6XGeSvX19Wi1Wt5///1mt3VHUegTdxzLz8/n9ttvZ/r06cybNw9/f392797NwoULMZvNqNXqThWu1+v1KJVK1qxZ0+xF28vLyymPQTh7KBQKtFotwcHBVFVVUVxcTFFRESEhIWi1WtzcRLU9oXvZbDYqKiooLi4GICwsjKCgIPEBShC6UZde+Sf0D293ltNqkxnxwncU1xhazFuVgDB/T7Y9MtqlZaxOlJiYyNdff40sy/bZyd27d+Pt7U1YWBh+fn6oVCr++usv+yxlbW0t2dnZDBkyBID4+HgsFgsHDhygX79+AOTk5DgsROrbty/l5eUolUqioqJaHcu+ffu46qqr7Nft27evS+Nvzf79+5FlmQULFthfbL/66iuHNikpKfz666/ce++9bY4BoHfv3litViorK+3PiyB0lSRJBAYGEhAQgE6no7i4mOLiYrRaLSEhIaKqheByFouF8vJySkpKUKlUREZGEhAQIFJTBOEUcPk0hVIh8dTEPtz5wR4kHLcebPqXf2piH5cFqrW1tRw8eNDhOo1Gw4wZM3jvvfd45plnmDlzJllZWSxZsoSbb74ZhUKBj48PV111FS+++CL+/v4EBQWxZMkSJEmyv1glJiYybNgwnnzySRYtWoSbmxvPP/88np6e9jbDhg1j0KBBzJ07l4ceeoi4uDhKS0v58ccfGTt2LP379+eGG25gwYIF9OvXj8GDB7Nx40aOHDlCdHR0q4+rvfG3JjY2FrPZzPvvv8/o0aPZvXs3//vf/xzazJkzh4kTJ7Jo0SKmTZuGSqVix44djB8/nsDAQIe28fHxTJw4kYcffpgFCxbQu3dvqqqq+PXXX0lJSeHiiy/uzK9LOAVSUlKcerxVq1YxdOhQ6urqePfdd9myZQt5eXlYrVZiYmK46KKLuOGGG+w5zm1pWojl7+9PXV0dxcXF/P333/j7+xMSEoKPj48IHoSTduTIEd5++2127NhBVVUVGo2GcePGMWnSJCwWC97e3sTGxvLdd98xefLkFo9x22238eCDDwIwevRoCgoKWmz3559/4uHhwdq1a3n00Uft1yuVSoKCghg+fDjz5s1r8f9ClmU+//xzPvvsM9LS0jCbzcTExDBu3DhuueWWVs9i6XQ6hg8fjslk4ssvvyQxMbFZmwULFrBu3Tr7ZS8vLwIDA+nbty+XX345l1xyiZhFFk65bjmnNr5fOG9eP7hZndWwbqizunPnTocZS4ApU6bwr3/9i6VLl/Liiy/y6aefotFomDJlCnfeeae93YIFC3jqqae444478PHx4dZbb6WoqAgPDw97mxdeeIGFCxcyc+ZMtFot8+fPJz093d5GkiSWLl3Ka6+9xqOPPkpVVRXBwcEMGTKE4OBgACZMmEBubi4vvfQSRqORcePGMX36dLZt29bq4woNDW13/C1JTU3l0Ucf5Z133uGVV15hyJAhzJ8/n0ceecTeJj4+nhUrVvDKK68wdepUPD09GTBgAFdccUWLx3zuued48803ef755yktLUWj0TBo0CARqJ4mXnzxRYfLn3/+Ob/88kuz6202m8ObVmvtEhMTycvL46abbqKoqIjx48dz3XXXoVKpSEtLY/Xq1fYFhp3h4+NDUlISRqORsrIyMjIycHd3R6vVEhgYKHIHhU7ZsmUL8+fPt792Jicn4+npiVqt5ptvvuGcc85h8ODBDve59957m50hS05Odrjcu3dvbr755mb9qVSqFo9lMpnYu3cv69atY/fu3WzatMnhPcZqtfLAAw/w1VdfMWTIEO6++27UajW7du3iv//9L19//TUrV660v58cb/PmzUiShFarZcOGDcybN6/F58Ld3Z3FixcDYDQaKSgo4Pvvv+fee+/l/PPP58033xQbGwinltwBDQ0N8oEDB+SGhoaONG+VxWqTt6eXy+v/yJe3p5fLFqutS8frbvX19fK5554rf/rpp622KSoqkpOTk+Xt27d348iEnsxZ/z/d5Z///KecnJx80u3MZrN85ZVXygMHDpR///33ZrfX1tbKr7zySpfHabVa5dLSUvnAgQPynj175OzsbLm+vr7LxxXOfDk5OfLAgQPlGTNmyEeOHJH37t0r//XXX3JxcbFcWloqjx8/Xh40aJCcm5sry7Isr1mzRk5OTpb//PPPNo87atQoec6cOW22ae1YL730kpycnCx/8cUXDte/9dZbcnJysvz88883O9a3334rp6amyrNnz26xr5kzZ8p33323/Oyzz8qjR49usc0jjzwiDxo0qMXb3n77bTk5OVm+77772nxMguBq3Tq3r1RIXJAYxKRBkVyQGNStOaon48CBA2zatInc3Fz2799vP9UzZswYe5tff/2Vb7/9lry8PPbs2cO8efOIjIwU+ZvCWWvLli0cOnSIO+64o8X/Ax8fn1ZneDqjaTFW7969SU5ORpZl0tLSOHjwIKWlpZjN7S/sFM4+VquVLVu2MG/ePObNm4dCoSA+Pp6+ffvaV/g//fTT6PV63nnnnW4bV9P/Sl5env06g8HA8uXLiYuL44EHHmh2n9GjR3PVVVfx888/s3fvXofbCgsL2bVrFxMmTODyyy8nPz+fPXv2dGpMc+bMYcSIEWzevJmsrKzOPyhBcBKxtLYdK1asICsrC5VKRd++ffnwww8d8jYtFguvvvoqeXl5eHt7c8455/Dyyy83O+UjCGeLb7/9FoBJkyZ1W5/e3t54e3sTHR1NZWUllZWV5Ofn4+vrS1BQEP7+/iJN4Cxms9nQ6XRUVlZSXV1NcHAwe/fuZcaMGS2+Vp933nlERkby448/OlxfV1dHZWWlw3Un5vFbLJZmbdRqdbPKLCdqynX18/OzX7d7925qamq44YYbWq2EcdVVV9lrXQ8aNMh+/aZN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AyfLgMZg2mq1Yjab7bOetbW11NTUUFlZSXl5OSUlJRQUFJCdnc2RI0fYv38/e/fu5Y8//uCvv/4iMzOT4uJiamtrUSgUBAYGEhcXx4ABAxg0aBC9e/cmISGBiIgIAgMDUavVIlAVBKHTXD6zKlutlDz7HLT0AirLIEmUPPscvmPGODUloKqqil9++YX58+fb83lO1JUXzX379rFw4ULmz5/P2LFj+fnnn1myZIlDm127dvHII4/w+OOPM2TIEHJzc3niiSeAxu33bDYb99xzD0FBQXz22WfU1tby7LPPttlvaWkpDzzwAA899BBjx46lvr6eXbt22d+gNmzYwL///W+efPJJevfuzcGDB3niiSfw8vJi8uTJDscKDw9n27ZtjB8/nnvvvZcJEybg6+vbat8vvvgijz32GElJSaxcuZI77riDb7/9loCAgGZtTSYTffv25bbbbsPHx4cffviBhx9+mJiYGAYMGMD48eNZvHgx3377LZdddhkAFRUV/PjjjyxfvrzVMezevbtZyZVVq1axcuVKnn76aXr37s2aNWu466672LRpU6dWsBoMBt555x0WL15sz0+86qqrmDp1Kq+88gpms5k///zT4e+mX79+WK1W9u3bx9ChQzvcl3B2c3Nzw8fHp8UanrIsY7FYMJvNzb7q6uqw2WxYrdZm308MUpv+To//e21q01JbhUKBUqm0f2/62c3NDXd3d7y9vXF3d7fP/Lq5uYnAUxCEbtGlYFW3eTNl/1mCrY3dNWwmE7YTSoM4kGUsxcUcHjESRTt1DBXe3mjvvRe/8ePaHVtubi6yLDfbGu/42bwZM2a0OYvXllWrVjFy5Ehuu+02AOLj4/njjz/4+eef7W1ef/115syZYw8So6Ojue+++3jppZe4++672b59O5mZmSxbtozQ0FAA5s2bZz9mS8rKyrBYLFxyySVERkYCjTmuTZYsWcKCBQu49GhqRXR0NOnp6XzyySfNgtWmfdQlSbIXym7LzJkzGTeu8blftGgRP//8M6tXr25xvKGhocyePdt+edasWWzbto2vvvqKAQMG4OnpyRVXXMHatWvtweqGDRsIDw9vNejT6XTU1tYSEhLicP3y5cu57bbbuPzyywF46KGH2LFjB++99x5PPfVUm4/peGazmUWLFtn32m6auRo1apR9VfCJdQvVajW+vr4UFhZ2uB9BaIskSfaAsDOaZkptNhuyLDsEpE0/Hx/ANgWoTV+CIAg9VZeC1YrlKzBlZjplILaqKmwd6XPFig4Fq61ZvXo1NpuNBx98sNkp6M7IyMhotgBq0KBBDsHqoUOH2LNnj8NqcavVitFopKGhgYyMDMLCwuyBKsA555zTZr+pqalccMEFTJw4kREjRjBixAjGjRuHv78/er2e3NxcFi5caJ/BhcaVy23NmB7vySefdKjBd3ydzOPH5ubmRr9+/chs5fdvtVp566232Lx5MyUlJfa8tuMXGF177bVMmTKFkpISQkNDWbt2LZMnT251tqbpVPvxxdnr6uooLS1l8ODBDm0HDx7MoUOHOvSYm6hUKofAX6PRcPXVVzN79myGDx/OBRdcwGWXXdYsWPbw8KChoaFTfQmCs0mSJLaLFQThjNSlV7ag2bMp+89/ujazepQiIKBDM6tBt9zSobHFxMQgSRJZWVkO10dHRwM4BE1NswrHz0Qcn1d6svR6Pffcc499lvN4rdXAa49SqWTlypXs2bOHX375hffff59XX32VTz/91F7Z4JlnnmHgwIEO9+vozMl9993nMCN6spYvX86qVavsubBqtZpnn33WoZh6nz59SE1NZf369QwfPpz09HSuvvrqVo+p0WiQJMkh97QjWvr9tlTUvaWFH8899xyzZs3i559/5quvvuK1115j5cqV9gLcADU1NfZFNYIgCIIgOFeXglW/8ePaneWUrVbSx4zFUlLSct6qJOEWGkrSt1udmrMaEBDA8OHD+eCDD7j++utbzVsF7IFGWVmZ/brjF1u1JDExkT///NPhun379jlc7tOnD1lZWcTGxrZ6jOLiYkpLS+2zdXv37m2zX2icQTn33HM599xzmTt3LqNGjWLr1q3cfPPNhISEkJeXx5VXXtnucVoSFBRkLxR9or1793LeeecBjcH8/v37mTlzZott9+zZw5gxY+z5pTabjezs7Gan0adMmcJ7771HSUkJw4YNa3MveXd3d5KSkkhPT2fEiBEA+Pj4EBISwp49ezj//PMd+h8wYADg+Pv19/cH6NSsa58+fejTpw+333471113HZs2bbIHq7m5uRiNRvr06dPh4wmCIAiC0HEuT1SSlEpCH3v06IUTTu8evRz62KMuqbf61FNPYbVaueaaa/jyyy/JyMggMzOTzz//nMzMTHudQ09PTwYNGsTSpUvJyMhg586dvPbaa20eu2m2bfny5WRnZ/PBBx84pAAAzJ07l88//5zXX3+dI0eOkJGRwRdffGHfNm/YsGHExcWxYMECDh06xK5du9rdhnLfvn289dZb/PXXXxQWFrJlyxYqKytJSEgA4N5772Xp0qWsWrWKrKws0tLSWLNmDStXrjzJZ/GYjz76iG+++YaMjAyefvppampquOaaa1psGxsby/bt29mzZw8ZGRk8+eSTlJeXN2s3ceJESkpK+PTTT1s91vFGjBjBnj17HK6bPXs277zzDl9++SWZmZm8/PLLHDp0yF7wOiYmhvDwcJYsWUJ2djY//PBDhzYUyMvL4//+7//4448/KCgoYNu2bWRnZ9ufa2hcRBcdHd3tO90IgiAIwtmiWxKc/C69FP79WvM6q6GhLq2zGhMTw7p163j77bf5v//7P0pKSlCpVCQlJXHLLbcwY8YMe9tnn32WhQsXcvXVVxMfH89DDz3ELW2kHAwaNIhnnnmGJUuW8J///IcLLriAO++802H3p5EjR/LWW2/x3//+l3feeQc3NzcSEhKYOnUq0Hh6+vXXX2fhwoVMmTKFyMhIHn/88Tb3o/bx8eH333/nvffeo66ujoiICBYsWMBFF10ENBb49/T0ZPny5bz44ot4eXmRnJzMjTfe2NWnkwceeIClS5dy8OBBYmNjefPNN1s9/X3nnXeSl5fH7NmzUavVXHvttYwdO5ba2lqHdr6+vlx66aX8+OOPHdoEYcqUKVxzzTXU1tba83BvuOEG6urqeP7556msrCQxMZE33njDXglApVLxf//3fyxatIgrr7yS/v37c//993Pfffe12ZdarSYzM5N169ZRXV1NSEgIM2fOZNq0afY2X3zxBddee2274xYEQRAE4eSc8TtYCV3X0q5XznTjjTfSq1cvHn/88Q61v/fee+nbty+3336708fSGUeOHOHGG2/k66+/bnMBm9jBShAEQRBOXrcuHZWUSryHnt9+Q+GsUFNTw86dO9m5c2enSkw9/PDDfP/99y4cWceUlZXxwgsvdLjSgiAIgiAInSfqnAinzOTJk6mpqeHBBx90yANtT1RUFLNmzXLhyDpm2LBhp3oIgiAIgnDGE8Gq0K6oqCjS0tKcftzvvvvO6ccUBEEQBOHMIrYtEQRBEARBEHosEawKgiAIgiAIPZYIVgVBEARBEIQeSwSrgiAIgiAIQo8lglVBEARBEAShxxLBqiAIgiAIgtBjiWBVEARBEARB6LG6tc6qbJMxZtVgqzWh8HXHI94fSSG5rL877rgDs9nM8uXLm922a9cuZs6cyeeff86kSZPs16tUKsLDw5k8eTJ33nknktQ4viVLlvD6668DoFQq8fX1JSkpiUsuuYQZM2bg7u7usschCIIgCIJwtuq2YLXh73KqN2ZgrTHZr1P6u6OZmIi6X7BL+pwyZQr33HMPxcXFhIWFOdy2Zs0a+vXrh4+PDwDvvvsuSUlJmEwmdu/ezeOPP45Wq2Xq1Kn2+/Tq1YuVK1dis9morq5m586dvPnmm2zYsIFVq1bZjyUIgiAIgiA4R7ekATT8XU7FBwcdAlUAa42Jig8O0vB3uUv6vfjiiwkMDGTt2rUO19fX17N582amTJliv06j0aDVaomMjOTKK69k8ODBHDhwwOF+SqUSrVZLaGgoKSkpzJo1i/fff5/Dhw/zzjvvuOQxCIIgCIIgnM1cHqzKNpnqjRlttqnemIlsk53et5ubG5MmTWLdunXI8rHjb968GZvNxhVXXNHi/f766y/279/PwIED2+0jMTGRCy+8kG+++cZp4xYEQRAEQRAadSkNQP9nGbpvcpCN1lbbyBYbNr2lzeNYa4wULf4Nya3t2FnyUOJ3aSxe/bUdHuM111zD8uXL2blzJ0OHDgVg7dq1XHrppfj6+lJTUwPAtGnTUCgUmM1mzGYz1113HVdddVWH+khISOCXX37p8JgEQRAEQRCEjulSsFr7Uz6WsganDKS9gPZYnwWdClYTExM555xzWLNmDUOHDiUnJ4ddu3axatUqh3avvvoqiYmJWCwWDh8+zOLFi/Hz8+PBBx9stw9Zlu0LsQRBEARBEATn6VIagO9FUbhp1Sj93Fv9Unh1LB5WeLm1eRylnztuWjW+F0Z2epxTpkxhy5Yt1NXVsXbtWmJiYjj//PMd2oSHhxMbG0tiYiKXXXYZN954IytXrsRoNLZ7/IyMDKKiojo9LkEQBEEQBKFtXZpZ9eqvbXeWU7bJFL+ws9niquMp/T0Ie+Q8l5Wxuuyyy/jXv/7Fpk2bWL9+PdOnT293JlShUGCxWDCbzXh4eLTaLiMjg23btjFnzhxnD1sQBEEQBOGs5/LSVZJCQjMxkYoPDrbaRjMxwaX1Vr29vZkwYQKvvPIKdXV1TJ48uVmb6upqysrKsFqtpKWlsWrVKoYOHepQjspqtVJWVtasdFVqaiqzZ8922fgFQRAEQRDOVt1SZ1XdL5ig63u3UGfVA83EBJfVWT3elClTWL16NRdddBGhoaHNbr/pppsax3S0PNVFF13EvHnzHNocOXKEESNG2DcFSExMZM6cOWJTAEEQBEEQBBeR5ONrOrXCYDCQlZVFfHw8np6eJ91Zd+9gJQg9gbP+fwRBEAThbNSt261KCgnPRE13dikIgiAIgiCcxrplBytBEARBEARBOBkiWBUEQRAEQRB6LBGsCoIgCIIgCD2WCFYFQRAEQRCEHksEq4IgCIIgCEKPJYJVQRAEQRAEoccSwaogCIIgCILQY4lgVRAEQRAEQeixRLDqQikpKWzduvVUD0MQBEEQBOG01a3BqlWW+aWqlnUlVfxSVYu1/Z1eu2TBggWkpKSQkpJC3759GT16NC+++CJGo9Gl/QrHiIBdEARBEISu6LbtVr8oq+bxIwUUGc3268I9VCzuFcnlWo3L+h05ciTPPfccFouF/fv388gjjyBJEg899JDL+hQEQRAEQRCco1tmVr8oq+bWv7MdAlWAYqOZW//O5ouyapf17e7ujlarJTw8nLFjxzJs2DC2b99uv72qqor58+czcuRIBg4cyMSJE9m0aZPDMWbNmsXixYt58cUXOf/88xk+fDhLlixxaJOdnc3MmTPp378/EyZM4Jdffmk2lrS0NG644QYGDBjA0KFDeeKJJ6ivr7ffvmDBAu666y7eeusthg0bxpAhQ3j99dexWCy88MILnH/++Vx44YWsWbOmzcf8008/MX36dIYMGcLQoUO5/fbbyc3NdWizZ88eJk2aRP/+/bn66qvZunUrKSkpHDx40N7m8OHD3HrrrZxzzjkMGzaMhx56iMrKyg4/L6NHjwZg7ty5pKSk2C8LgiAIgiB0lMuDVass8/iRAlo64d903RNHClyeEgCNwdcff/yBSqWyX2cymejbty9Lly5l06ZNXHvttTz88MP8+eefDvddt24dXl5efPrppzz00EP897//tQekNpuNe+65B5VKxWeffcY///lPXn75ZYf76/V6Zs+ejb+/P6tXr+a1115j+/btPPPMMw7tfvvtN0pLS/nggw9YsGABS5Ys4fbbb8ff359PP/2UadOm8dRTT1FcXNzq42xo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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "radar_fig = create_radar_chart(data_dir='../figures_data')\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "gpudrive",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/examples/eval/process.py b/examples/eval/process.py
new file mode 100644
index 000000000..ce0f4a42a
--- /dev/null
+++ b/examples/eval/process.py
@@ -0,0 +1,93 @@
+if __name__ == "__main__":
+
+ import os
+ import shutil
+ from pathlib import Path
+
+ # Define the source folder paths
+ validation_folder = "data/processed/wosac/validation"
+ validation_extracted_folder = "data/processed/wosac/validation_extracted"
+
+ # Define the destination folder paths
+ validation_json_folder = "validation_json"
+ validation_tfrecord_folder = "validation_tfrecord"
+
+ # Create destination folders if they don't exist
+ os.makedirs(validation_json_folder, exist_ok=True)
+ os.makedirs(validation_tfrecord_folder, exist_ok=True)
+
+ # Check if source folders exist
+ if not os.path.exists(validation_folder):
+ print(f"Error: Folder '{validation_folder}' does not exist.")
+ exit(1)
+
+ if not os.path.exists(validation_extracted_folder):
+ print(f"Error: Folder '{validation_extracted_folder}' does not exist.")
+ exit(1)
+
+ # Get all files and extract base names (without extension)
+ validation_files = {}
+ validation_extracted_files = {}
+
+ # Process validation folder (json files)
+ for filename in os.listdir(validation_folder):
+ if filename.endswith('.json'):
+ base_name = Path(filename).stem # Gets filename without extension
+ validation_files[base_name] = filename
+
+ # Process validation_extracted folder (tfrecords files)
+ for filename in os.listdir(validation_extracted_folder):
+ if filename.endswith('.tfrecords'):
+ base_name = Path(filename).stem # Gets filename without extension
+ validation_extracted_files[base_name] = filename
+
+ # Find matches
+ matches = set(validation_files.keys()) & set(validation_extracted_files.keys())
+
+ print(f"Total matches found: {len(matches)}")
+
+ # Check if we have at least 500 matches
+ if len(matches) < 500:
+ print(f"Warning: Only {len(matches)} matches found, less than requested 500")
+ files_to_copy = sorted(matches)
+ else:
+ # Take first 500 matches (sorted alphabetically for consistency)
+ files_to_copy = sorted(matches)[:500]
+ print(f"Copying first 500 matches out of {len(matches)}")
+
+ # Copy matching files
+ copied_count = 0
+ for base_name in files_to_copy:
+ try:
+ # Copy json file
+ json_src = os.path.join(validation_folder, validation_files[base_name])
+ json_dst = os.path.join(validation_json_folder, validation_files[base_name])
+ shutil.copy2(json_src, json_dst)
+
+ # Copy tfrecords file
+ tf_src = os.path.join(validation_extracted_folder, validation_extracted_files[base_name])
+ tf_dst = os.path.join(validation_tfrecord_folder, validation_extracted_files[base_name])
+ shutil.copy2(tf_src, tf_dst)
+
+ copied_count += 1
+ if copied_count % 50 == 0: # Progress update every 50 files
+ print(f"Copied {copied_count} files...")
+
+ except Exception as e:
+ print(f"Error copying files for {base_name}: {e}")
+
+ print(f"\nSuccessfully copied {copied_count} matching files:")
+ print(f"JSON files in: {validation_json_folder}")
+ print(f"TFRecord files in: {validation_tfrecord_folder}")
+
+ # Write a summary file
+ with open("copied_files_summary.txt", 'w') as f:
+ f.write(f"Copied Files Summary\n")
+ f.write(f"===================\n\n")
+ f.write(f"Total matches found: {len(matches)}\n")
+ f.write(f"Files copied: {copied_count}\n\n")
+ f.write("Copied files:\n")
+ for base_name in files_to_copy:
+ f.write(f" {validation_files[base_name]} <-> {validation_extracted_files[base_name]}\n")
+
+ print(f"Summary written to: copied_files_summary.txt")
\ No newline at end of file
diff --git a/examples/eval/run_wosac_eval.py b/examples/eval/run_wosac_eval.py
new file mode 100644
index 000000000..0a7e4f654
--- /dev/null
+++ b/examples/eval/run_wosac_eval.py
@@ -0,0 +1,235 @@
+import torch
+import dataclasses
+import os
+import sys
+import mediapy
+from tqdm import tqdm
+
+from gpudrive.env.config import EnvConfig
+from gpudrive.env.env_torch import GPUDriveTorchEnv
+from gpudrive.env.dataset import SceneDataLoader
+from gpudrive.datatypes.observation import GlobalEgoState
+from gpudrive.utils.checkpoint import load_agent
+
+# WOSAC
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from waymo_open_dataset.protos import sim_agents_submission_pb2
+from eval.wosac_eval import WOSACMetrics
+
+
+def get_state(env):
+ """Obtain raw agent states."""
+ ego_state = GlobalEgoState.from_tensor(
+ env.sim.absolute_self_observation_tensor(),
+ backend=env.backend,
+ device=env.device,
+ )
+ mean_xy = env.sim.world_means_tensor().to_torch()[:, :2]
+ mean_x = mean_xy[:, 0].unsqueeze(1)
+ mean_y = mean_xy[:, 1].unsqueeze(1)
+ return (
+ ego_state.pos_x + mean_x,
+ ego_state.pos_y + mean_y,
+ ego_state.pos_z,
+ ego_state.rotation_angle,
+ ego_state.id,
+ )
+
+
+def rollout(
+ env,
+ sim_agent,
+ init_steps,
+ num_envs,
+ max_agents,
+ device,
+):
+ """Rollout agent in the environment and return the scenario rollouts."""
+
+ next_obs = env.reset()
+
+ scenario_ids = list(env.get_scenario_ids().values())
+
+ pos_x_list = []
+ pos_y_list = []
+ pos_z_list = []
+ heading_list = []
+ done_list = [env.get_dones()]
+
+ control_mask = env.cont_agent_mask
+
+ pos_x, pos_y, pos_z, heading, _ = get_state(env)
+
+ for time_step in range(env.episode_len - init_steps):
+
+ # Predict actions
+ action, _, _, _ = sim_agent(next_obs[control_mask])
+
+ action_template = torch.zeros(
+ (num_envs, max_agents), dtype=torch.int64, device=device
+ )
+ action_template[control_mask] = action.to(device)
+
+ # Step
+ env.step_dynamics(action_template)
+
+ next_obs = env.get_obs()
+ done = env.get_dones()
+
+ pos_x, pos_y, pos_z, heading, id = get_state(env)
+
+ pos_x_list.append(pos_x)
+ pos_y_list.append(pos_y)
+ pos_z_list.append(pos_z)
+ heading_list.append(heading)
+ done_list.append(done)
+ _ = done_list.pop()
+
+ # Generate Scenario
+ pos_x_stack = torch.stack(pos_x_list, dim=-1).cpu().numpy()
+ pos_y_stack = torch.stack(pos_y_list, dim=-1).cpu().numpy()
+ pos_z_stack = torch.stack(pos_z_list, dim=-1).cpu().numpy()
+ heading_stack = torch.stack(heading_list, dim=-1).cpu().numpy()
+ done_stack = torch.stack(done_list, dim=-1).cpu().numpy()
+ id = id.cpu().numpy()
+ control_mask = control_mask.cpu().numpy()
+
+ scenario_rollouts = []
+ scenario_rollout_masks = []
+ for i, scenario_id in enumerate(scenario_ids):
+ # control_mask_i = id[i] != 0
+ control_mask_i = control_mask[i]
+ scenario_rollout_masks.append(done_stack[i, control_mask_i] == 0)
+ pos_x_i = pos_x_stack[i, control_mask_i]
+ pos_y_i = pos_y_stack[i, control_mask_i]
+ pos_z_i = pos_z_stack[i, control_mask_i]
+ heading_i = heading_stack[i, control_mask_i]
+ id_i = id[i, control_mask_i]
+
+ simulated_trajectories = []
+ for a, obj_i_a in enumerate(id_i):
+ simulated_trajectories.append(
+ sim_agents_submission_pb2.SimulatedTrajectory(
+ center_x=pos_x_i[a],
+ center_y=pos_y_i[a],
+ center_z=pos_z_i[a],
+ heading=heading_i[a],
+ object_id=int(obj_i_a),
+ )
+ )
+ joint_scene = sim_agents_submission_pb2.JointScene(
+ simulated_trajectories=simulated_trajectories
+ )
+
+ scenario_rollouts.append(
+ sim_agents_submission_pb2.ScenarioRollouts(
+ joint_scenes=[joint_scene],
+ scenario_id=scenario_id,
+ )
+ )
+
+ return scenario_ids, scenario_rollouts, scenario_rollout_masks
+
+
+if __name__ == "__main__":
+
+ # Settings
+ MAX_AGENTS = 64
+ NUM_ENVS = 1
+ DEVICE = "cpu"
+ NUM_BATCHES = 1
+ NUM_ROLLOUTS = 10
+ INIT_STEPS = 10
+ DATASET_SIZE = 100
+
+ DATA_JSON = "data/processed/wosac/validation_json_1"
+ DATA_TFRECORD = "data/processed/wosac/validation_tfrecord_1"
+
+ # Create data loader
+ val_loader = SceneDataLoader(
+ root=DATA_JSON,
+ batch_size=NUM_ENVS,
+ dataset_size=DATASET_SIZE,
+ sample_with_replacement=True,
+ file_prefix="",
+ )
+
+ # Load agent
+ agent = load_agent(
+ path_to_cpt="checkpoints/model_waypoint_rs__S_1__04_23_19_37_26_618_003500.pt",
+ )
+
+ # Obtain config directly from the agent checkpoint
+ config = agent.config
+
+ # Configs
+ env_config = dataclasses.replace(
+ EnvConfig(),
+ ego_state=config.ego_state,
+ road_map_obs=config.road_map_obs,
+ partner_obs=config.partner_obs,
+ reward_type=config.reward_type,
+ norm_obs=config.norm_obs,
+ dynamics_model=config.dynamics_model,
+ collision_behavior=config.collision_behavior,
+ polyline_reduction_threshold=config.polyline_reduction_threshold,
+ obs_radius=config.obs_radius,
+ steer_actions=torch.round(
+ torch.linspace(
+ -torch.pi / 3, torch.pi / 3, config.action_space_steer_disc
+ ),
+ decimals=3,
+ ),
+ accel_actions=torch.round(
+ torch.linspace(-4.0, 4.0, config.action_space_accel_disc),
+ decimals=3,
+ ),
+ remove_non_vehicles=config.remove_non_vehicles,
+ init_mode="womd_tracks_to_predict",
+ init_steps=INIT_STEPS,
+ goal_behavior="stop",
+ add_reference_path=config.add_reference_path,
+ add_reference_speed=config.add_reference_speed,
+ )
+
+ env = GPUDriveTorchEnv(
+ config=env_config,
+ data_loader=val_loader,
+ max_cont_agents=MAX_AGENTS,
+ device=DEVICE,
+ )
+ wosac_metrics = WOSACMetrics()
+
+ for _ in tqdm(range(NUM_BATCHES)):
+ for _ in range(NUM_ROLLOUTS):
+ # try:
+ scenario_ids, scenario_rollouts, scenario_rollout_masks = rollout(
+ env=env,
+ sim_agent=agent,
+ init_steps=INIT_STEPS,
+ num_envs=NUM_ENVS,
+ max_agents=MAX_AGENTS,
+ device=DEVICE,
+ )
+ # except Exception as e:
+ # print(f"Error during rollout: {e}")
+ # continue
+
+ tf_record_paths = [
+ os.path.join(DATA_TFRECORD, f"{scenario_id}.tfrecords")
+ for scenario_id in scenario_ids
+ ]
+ wosac_metrics.update(
+ tf_record_paths,
+ scenario_rollouts,
+ # scenario_rollout_masks=scenario_rollout_masks
+ )
+ try:
+ env.swap_data_batch()
+ except Exception as e:
+ break
+
+ results = wosac_metrics.compute()
+
+ for key, value in results.items():
+ print(f"{key}: {value}")
diff --git a/examples/eval/wosac_eval.py b/examples/eval/wosac_eval.py
new file mode 100644
index 000000000..d064d1ad6
--- /dev/null
+++ b/examples/eval/wosac_eval.py
@@ -0,0 +1,341 @@
+from pathlib import Path
+from typing import Dict, List, Optional
+
+import tensorflow as tf
+
+# import waymo_open_dataset.wdl_limited.sim_agents_metrics.metrics as wosac_metrics
+import wosac_metrics.metrics as wosac_metrics
+import pandas as pd
+import numpy as np
+import datetime
+
+from google.protobuf import text_format
+from torch import Tensor, tensor
+from torchmetrics import Metric
+from waymo_open_dataset.protos import (
+ scenario_pb2,
+ sim_agents_metrics_pb2,
+ sim_agents_submission_pb2,
+)
+
+
+class WOSACMetrics(Metric):
+ """
+ Validation metrics based on ground truth trajectories, using waymo_open_dataset api.
+ https://waymo.com/open/challenges/2025/sim-agents/
+ """
+
+ def __init__(
+ self,
+ prefix: str = "",
+ ego_only: bool = False,
+ baselines_df: Optional[pd.DataFrame] = None,
+ save_table_with_baselines: bool = True,
+ ) -> None:
+ super().__init__()
+ self.is_mp_init = False
+ self.prefix = prefix
+ self.ego_only = ego_only
+ self.wosac_config = wosac_metrics.load_metrics_config()
+ self.save_table_with_baselines = save_table_with_baselines
+
+ # Initialize baseline df if not provided
+ if baselines_df is None:
+ self.baselines_df = self._create_baselines_df()
+ else:
+ self.baselines_df = baselines_df
+
+ self.timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H")
+
+ self.field_names = [
+ "metametric",
+ "average_displacement_error",
+ "linear_speed_likelihood",
+ "linear_acceleration_likelihood",
+ "angular_speed_likelihood",
+ "angular_acceleration_likelihood",
+ "distance_to_nearest_object_likelihood",
+ "collision_indication_likelihood",
+ "time_to_collision_likelihood",
+ "distance_to_road_edge_likelihood",
+ "offroad_indication_likelihood",
+ "min_average_displacement_error",
+ "simulated_collision_rate",
+ "simulated_offroad_rate",
+ ]
+ for k in self.field_names:
+ self.add_state(k, default=tensor(0.0), dist_reduce_fx="sum")
+ self.add_state(
+ "scenario_counter", default=tensor(0.0), dist_reduce_fx="sum"
+ )
+ tf.config.set_visible_devices([], "GPU")
+
+ def _create_baselines_df(self) -> pd.DataFrame:
+ """Create a DataFrame with baseline metrics based on the provided table."""
+ columns = [
+ "AGENT POLICY",
+ "REPLAN RATE (Hz)",
+ "LINEAR SPEED (↑)",
+ "LINEAR ACCEL. (↑)",
+ "ANG. SPEED (↑)",
+ "ANG. ACCEL. (↑)",
+ "DIST. TO OBJ. (↑)",
+ "COLLISION (↑)",
+ "TTC (↑)",
+ "DIST. TO ROAD EDGE (↑)",
+ "OFFROAD (↑)",
+ "COMPOSITE METRIC (↑)",
+ "ADE (↓)",
+ "MINADE (↓)",
+ "COLLISION RATE (↓)",
+ "OFFROAD RATE (↓)",
+ ]
+
+ data = [
+ # Logged Oracle values
+ [
+ "Logged oracle",
+ "-",
+ 0.476,
+ 0.478,
+ 0.578,
+ 0.694,
+ 0.476,
+ 1.000,
+ 0.883,
+ 0.715,
+ 1.000,
+ 0.819,
+ 0.000,
+ 0.000,
+ 0.028,
+ 0.111,
+ ],
+ # Versatile Behavior Diffusion
+ [
+ "VBD",
+ 0.125,
+ 0.359,
+ 0.366,
+ 0.420,
+ 0.522,
+ 0.368,
+ 0.934,
+ 0.815,
+ 0.651,
+ 0.879,
+ 0.720,
+ 2.257,
+ 1.474,
+ 0.036,
+ 0.152,
+ ],
+ ]
+
+ # Other rows from the table can be added as needed
+ data.extend(
+ [
+ [
+ "Random agent",
+ 10,
+ 0.002,
+ 0.116,
+ 0.014,
+ 0.034,
+ 0.000,
+ 0.000,
+ 0.735,
+ 0.148,
+ 0.191,
+ 0.144,
+ 50.739,
+ 50.706,
+ 1.000,
+ 0.613,
+ ],
+ ]
+ )
+
+ return pd.DataFrame(data, columns=columns)
+
+ @staticmethod
+ def _compute_scenario_metrics(
+ config,
+ scenario_file,
+ scenario_rollout,
+ ego_only,
+ scenario_rollouts_mask=None,
+ ) -> sim_agents_metrics_pb2.SimAgentMetrics:
+ scenario = scenario_pb2.Scenario()
+ for data in tf.data.TFRecordDataset(
+ [scenario_file], compression_type=""
+ ):
+ scenario.ParseFromString(bytes(data.numpy()))
+ break
+ if ego_only:
+ for i in range(len(scenario.tracks)):
+ if i != scenario.sdc_track_index:
+ for t in range(91):
+ scenario.tracks[i].states[t].valid = False
+ while len(scenario.tracks_to_predict) > 1:
+ scenario.tracks_to_predict.pop()
+ scenario.tracks_to_predict[
+ 0
+ ].track_index = scenario.sdc_track_index
+
+ return wosac_metrics.compute_scenario_metrics_for_bundle(
+ config,
+ scenario,
+ scenario_rollout,
+ scenario_rollouts_mask=scenario_rollouts_mask,
+ )
+
+ def update(
+ self,
+ scenario_files: List[str],
+ scenario_rollouts: List[sim_agents_submission_pb2.ScenarioRollouts],
+ scenario_rollout_masks=None,
+ ) -> None:
+
+ if scenario_rollout_masks is None:
+ scenario_rollout_masks = [None] * len(scenario_rollouts)
+ pool_scenario_metrics = []
+ for _scenario, _scenario_rollout, _scenario_mask in zip(
+ scenario_files, scenario_rollouts, scenario_rollout_masks
+ ):
+ try:
+ pool_scenario_metrics.append(
+ self._compute_scenario_metrics(
+ self.wosac_config,
+ _scenario,
+ _scenario_rollout,
+ self.ego_only,
+ # scenario_rollouts_mask=_scenario_mask
+ )
+ )
+ except Exception as e:
+ print(
+ f"Error processing scenario {_scenario_rollout.scenario_id}"
+ )
+ print(e)
+
+ for scenario_metrics in pool_scenario_metrics:
+ self.scenario_counter += 1
+ self.metametric += scenario_metrics.metametric
+ self.average_displacement_error += (
+ scenario_metrics.average_displacement_error
+ )
+ self.linear_speed_likelihood += (
+ scenario_metrics.linear_speed_likelihood
+ )
+ self.linear_acceleration_likelihood += (
+ scenario_metrics.linear_acceleration_likelihood
+ )
+ self.angular_speed_likelihood += (
+ scenario_metrics.angular_speed_likelihood
+ )
+ self.angular_acceleration_likelihood += (
+ scenario_metrics.angular_acceleration_likelihood
+ )
+ self.distance_to_nearest_object_likelihood += (
+ scenario_metrics.distance_to_nearest_object_likelihood
+ )
+ self.collision_indication_likelihood += (
+ scenario_metrics.collision_indication_likelihood
+ )
+ self.time_to_collision_likelihood += (
+ scenario_metrics.time_to_collision_likelihood
+ )
+ self.distance_to_road_edge_likelihood += (
+ scenario_metrics.distance_to_road_edge_likelihood
+ )
+ self.offroad_indication_likelihood += (
+ scenario_metrics.offroad_indication_likelihood
+ )
+ self.min_average_displacement_error += (
+ scenario_metrics.min_average_displacement_error
+ )
+ self.simulated_collision_rate += (
+ scenario_metrics.simulated_collision_rate
+ )
+ self.simulated_offroad_rate += (
+ scenario_metrics.simulated_offroad_rate
+ )
+
+ def compute(self) -> Dict[str, Tensor]:
+ metrics_dict = {}
+ for k in self.field_names:
+ metrics_dict[k] = getattr(self, k) / self.scenario_counter
+
+ mean_metrics = sim_agents_metrics_pb2.SimAgentMetrics(
+ scenario_id="", **metrics_dict
+ )
+ final_metrics = wosac_metrics.aggregate_metrics_to_buckets(
+ self.wosac_config, mean_metrics
+ )
+
+ out_dict = {
+ f"{self.prefix}/wosac/realism_meta_metric": final_metrics.realism_meta_metric,
+ f"{self.prefix}/wosac/kinematic_metrics": final_metrics.kinematic_metrics,
+ f"{self.prefix}/wosac/interactive_metrics": final_metrics.interactive_metrics,
+ f"{self.prefix}/wosac/map_based_metrics": final_metrics.map_based_metrics,
+ f"{self.prefix}/wosac/min_ade": final_metrics.min_ade,
+ f"{self.prefix}/wosac/scenario_counter": self.scenario_counter,
+ }
+ for k in self.field_names:
+ out_dict[f"{self.prefix}/wosac_likelihood/{k}"] = metrics_dict[k]
+
+ if self.save_table_with_baselines:
+ self._add_current_method_to_baselines(metrics_dict, final_metrics)
+
+ table_name = f"wosac_table_{self.timestamp}.csv"
+ self.baselines_df.to_csv(table_name, index=False)
+ print(f"Saved df to {table_name}")
+
+ return out_dict
+
+ def _add_current_method_to_baselines(self, metrics_dict, final_metrics):
+ """Add the current method's metrics to the baselines dataframe."""
+ new_row = {
+ "AGENT POLICY": "Guided self-play (ours)",
+ "REPLAN RATE (Hz)": 10,
+ "LINEAR SPEED (↑)": metrics_dict["linear_speed_likelihood"].item(),
+ "LINEAR ACCEL. (↑)": metrics_dict[
+ "linear_acceleration_likelihood"
+ ].item(),
+ "ANG. SPEED (↑)": metrics_dict["angular_speed_likelihood"].item(),
+ "ANG. ACCEL. (↑)": metrics_dict[
+ "angular_acceleration_likelihood"
+ ].item(),
+ "DIST. TO OBJ. (↑)": metrics_dict[
+ "distance_to_nearest_object_likelihood"
+ ].item(),
+ "COLLISION (↑)": metrics_dict[
+ "collision_indication_likelihood"
+ ].item(),
+ "TTC (↑)": metrics_dict["time_to_collision_likelihood"].item(),
+ "DIST. TO ROAD EDGE (↑)": metrics_dict[
+ "distance_to_road_edge_likelihood"
+ ].item(),
+ "OFFROAD (↑)": metrics_dict[
+ "offroad_indication_likelihood"
+ ].item(),
+ "COMPOSITE METRIC (↑)": final_metrics.realism_meta_metric,
+ "ADE (↓)": metrics_dict["average_displacement_error"].item(),
+ "MINADE (↓)": metrics_dict[
+ "min_average_displacement_error"
+ ].item(),
+ "COLLISION RATE (↓)": metrics_dict[
+ "simulated_collision_rate"
+ ].item(),
+ "OFFROAD RATE (↓)": metrics_dict["simulated_offroad_rate"].item(),
+ }
+
+ self.baselines_df = pd.concat(
+ [self.baselines_df, pd.DataFrame([new_row])], ignore_index=True
+ )
+
+ # Optional: Sort the dataframe by a performance metric, such as COMPOSITE METRIC
+ self.baselines_df = self.baselines_df.sort_values(
+ by="COMPOSITE METRIC (↑)", ascending=False
+ )
diff --git a/examples/eval/wosac_eval_origin.py b/examples/eval/wosac_eval_origin.py
new file mode 100644
index 000000000..55a581816
--- /dev/null
+++ b/examples/eval/wosac_eval_origin.py
@@ -0,0 +1,169 @@
+import itertools
+import multiprocessing as mp
+import os
+from pathlib import Path
+from typing import Dict, List
+
+import tensorflow as tf
+import waymo_open_dataset.wdl_limited.sim_agents_metrics.metrics as wosac_metrics
+# import eval.wosac_metrics.metrics as wosac_metrics
+
+from google.protobuf import text_format
+from torch import Tensor, tensor
+from torchmetrics import Metric
+from waymo_open_dataset.protos import (
+ scenario_pb2,
+ sim_agents_metrics_pb2,
+ sim_agents_submission_pb2,
+)
+
+
+class WOSACMetrics(Metric):
+ """
+ validation metrics based on ground truth trajectory, using waymo_open_dataset api
+ """
+
+ def __init__(self, prefix: str = "", ego_only: bool = False) -> None:
+ super().__init__()
+ self.is_mp_init = False
+ self.prefix = prefix
+ self.ego_only = ego_only
+ self.wosac_config = load_metrics_config()
+
+ self.field_names = [
+ "metametric",
+ "average_displacement_error",
+ "linear_speed_likelihood",
+ "linear_acceleration_likelihood",
+ "angular_speed_likelihood",
+ "angular_acceleration_likelihood",
+ "distance_to_nearest_object_likelihood",
+ "collision_indication_likelihood",
+ "time_to_collision_likelihood",
+ "distance_to_road_edge_likelihood",
+ "offroad_indication_likelihood",
+ "min_average_displacement_error",
+ "simulated_collision_rate",
+ "simulated_offroad_rate",
+ ]
+ for k in self.field_names:
+ self.add_state(k, default=tensor(0.0), dist_reduce_fx="sum")
+ self.add_state("scenario_counter", default=tensor(0.0), dist_reduce_fx="sum")
+ tf.config.set_visible_devices([], "GPU")
+
+ @staticmethod
+ def _compute_scenario_metrics(
+ config, scenario_file, scenario_rollout, ego_only, scenario_rollouts_mask=None
+ ) -> sim_agents_metrics_pb2.SimAgentMetrics:
+ scenario = scenario_pb2.Scenario()
+ for data in tf.data.TFRecordDataset([scenario_file], compression_type=""):
+ scenario.ParseFromString(bytes(data.numpy()))
+ break
+ if ego_only:
+ for i in range(len(scenario.tracks)):
+ if i != scenario.sdc_track_index:
+ for t in range(91):
+ scenario.tracks[i].states[t].valid = False
+ while len(scenario.tracks_to_predict) > 1:
+ scenario.tracks_to_predict.pop()
+ scenario.tracks_to_predict[0].track_index = scenario.sdc_track_index
+
+ return wosac_metrics.compute_scenario_metrics_for_bundle(
+ config, scenario, scenario_rollout,# scenario_rollouts_mask=scenario_rollouts_mask
+ )
+
+ def update(
+ self,
+ scenario_files: List[str],
+ scenario_rollouts: List[sim_agents_submission_pb2.ScenarioRollouts],
+ scenario_rollout_masks = None,
+ ) -> None:
+
+ if scenario_rollout_masks is None:
+ scenario_rollout_masks = [None] * len(scenario_rollouts)
+ pool_scenario_metrics = []
+ for _scenario, _scenario_rollout, _scenario_mask in zip(scenario_files, scenario_rollouts, scenario_rollout_masks):
+ try:
+ pool_scenario_metrics.append(
+ self._compute_scenario_metrics(
+ self.wosac_config, _scenario, _scenario_rollout, self.ego_only,
+ # scenario_rollouts_mask=_scenario_mask
+ )
+ )
+ except Exception as e:
+ print(f"Error processing scenario {_scenario_rollout.scenario_id}")
+ print(e)
+
+ for scenario_metrics in pool_scenario_metrics:
+ self.scenario_counter += 1
+ self.metametric += scenario_metrics.metametric
+ self.average_displacement_error += (
+ scenario_metrics.average_displacement_error
+ )
+ self.linear_speed_likelihood += scenario_metrics.linear_speed_likelihood
+ self.linear_acceleration_likelihood += (
+ scenario_metrics.linear_acceleration_likelihood
+ )
+ self.angular_speed_likelihood += scenario_metrics.angular_speed_likelihood
+ self.angular_acceleration_likelihood += (
+ scenario_metrics.angular_acceleration_likelihood
+ )
+ self.distance_to_nearest_object_likelihood += (
+ scenario_metrics.distance_to_nearest_object_likelihood
+ )
+ self.collision_indication_likelihood += (
+ scenario_metrics.collision_indication_likelihood
+ )
+ self.time_to_collision_likelihood += (
+ scenario_metrics.time_to_collision_likelihood
+ )
+ self.distance_to_road_edge_likelihood += (
+ scenario_metrics.distance_to_road_edge_likelihood
+ )
+ self.offroad_indication_likelihood += (
+ scenario_metrics.offroad_indication_likelihood
+ )
+ self.min_average_displacement_error += (
+ scenario_metrics.min_average_displacement_error
+ )
+ self.simulated_collision_rate += scenario_metrics.simulated_collision_rate
+ self.simulated_offroad_rate += scenario_metrics.simulated_offroad_rate
+
+ def compute(self) -> Dict[str, Tensor]:
+ metrics_dict = {}
+ for k in self.field_names:
+ metrics_dict[k] = getattr(self, k) / self.scenario_counter
+
+ mean_metrics = sim_agents_metrics_pb2.SimAgentMetrics(
+ scenario_id="", **metrics_dict
+ )
+ final_metrics = wosac_metrics.aggregate_metrics_to_buckets(
+ self.wosac_config, mean_metrics
+ )
+
+ out_dict = {
+ f"{self.prefix}/wosac/realism_meta_metric": final_metrics.realism_meta_metric,
+ f"{self.prefix}/wosac/kinematic_metrics": final_metrics.kinematic_metrics,
+ f"{self.prefix}/wosac/interactive_metrics": final_metrics.interactive_metrics,
+ f"{self.prefix}/wosac/map_based_metrics": final_metrics.map_based_metrics,
+ f"{self.prefix}/wosac/min_ade": final_metrics.min_ade,
+ f"{self.prefix}/wosac/scenario_counter": self.scenario_counter,
+ }
+ for k in self.field_names:
+ out_dict[f"{self.prefix}/wosac_likelihood/{k}"] = metrics_dict[k]
+
+ return out_dict
+
+
+def load_metrics_config() -> sim_agents_metrics_pb2.SimAgentMetricsConfig:
+ """Loads the `SimAgentMetricsConfig` used for the challenge."""
+ # pylint: disable=line-too-long
+ # pyformat: disable
+ import waymo_open_dataset
+ config_path = '{pyglib_resource}/wdl_limited/sim_agents_metrics/challenge_2024_config.textproto'.format(
+ pyglib_resource=waymo_open_dataset.__path__[0]
+ )
+ with open(config_path, 'r') as f:
+ config = sim_agents_metrics_pb2.SimAgentMetricsConfig()
+ text_format.Parse(f.read(), config)
+ return config
\ No newline at end of file
diff --git a/examples/eval/wosac_metrics/__init__.py b/examples/eval/wosac_metrics/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/examples/eval/wosac_metrics/metric_features.py b/examples/eval/wosac_metrics/metric_features.py
new file mode 100644
index 000000000..ac0dbb8a6
--- /dev/null
+++ b/examples/eval/wosac_metrics/metric_features.py
@@ -0,0 +1,437 @@
+# Copyright (c) 2024 Waymo LLC. All rights reserved.
+
+# This is licensed under a BSD+Patent license.
+# Please see LICENSE and PATENTS text files.
+# ==============================================================================
+"""Simulation features used for sim agent metrics."""
+
+from __future__ import annotations
+
+import collections
+import dataclasses
+
+import tensorflow as tf
+
+from waymo_open_dataset.protos import scenario_pb2
+from waymo_open_dataset.protos import sim_agents_submission_pb2
+from waymo_open_dataset.utils import trajectory_utils
+from waymo_open_dataset.utils.sim_agents import converters
+from waymo_open_dataset.utils.sim_agents import submission_specs
+from waymo_open_dataset.wdl_limited.sim_agents_metrics import interaction_features
+from waymo_open_dataset.wdl_limited.sim_agents_metrics import map_metric_features
+from waymo_open_dataset.wdl_limited.sim_agents_metrics import trajectory_features
+
+
+@dataclasses.dataclass(frozen=True)
+class MetricFeatures:
+ """Collection of features used to compute sim-agent metrics.
+
+ These features may be a function of simulated data (e.g. dynamics and
+ collisions), logged data (e.g. displacement) and map features (e.g. offroad).
+
+ This class can be used to represent both features coming from the original
+ Scenario and features from simulation. The samples dimension is set
+ accordingly depending on the source (n_samples=1 for log and n_samples=32 for
+ simulation).
+
+ Some of the features are computed in 3D (x/y/z) to have better consistency
+ with the original data and making these metrics more suitable for future
+ updates.
+
+ Attributes:
+ object_id: A tensor of shape (n_objects,), containing the integer IDs of all
+ the evaluated objects. The object_id tensor is not batched because all the
+ objects need to be consistent over samples for proper evaluation.
+ valid: Boolean tensor of shape (n_samples, n_objects, n_steps), identifying
+ which objects are valid over time. This is used to filter the features
+ when computing metrics.
+ average_displacement_error: Per-object average (over time) displacement
+ error compared to the logged trajectory. Shape: (n_samples, n_objects).
+ linear_speed: Linear speed in 3D computed as the 1-step difference between
+ trajectory points. Shape: (n_samples, n_objects, n_steps).
+ linear_acceleration: Linear acceleration in 3D computed as the 1-step
+ difference between speeds of objects.
+ Shape: (n_samples, n_objects, n_steps).
+ angular_speed: Angular speed computed as the 1-step difference in heading.
+ Shape: (n_samples, n_objects, n_steps).
+ angular_acceleration: Angular acceleration computed as the 1-step difference
+ in angular_speed. Shape: (n_samples, n_objects, n_steps).
+ distance_to_nearest_object: Signed distance (in meters) to the nearest
+ object in the scene. Shape: (n_samples, n_objects, n_steps).
+ collision_per_step: Boolean tensor indicating whether the object collided,
+ with any other object. Shape: (n_samples, n_objects, n_steps).
+ time_to_collision: Time (in seconds) before the object collides with the
+ object it is following (if it exists), assuming constant speeds.
+ Shape: (n_samples, n_objects, n_steps).
+ distance_to_road_edge: Signed distance (in meters) to the nearest road edge
+ in the scene. Shape: (n_samples, n_objects, n_steps).
+ offroad_per_step: Boolean tensor indicating whether the object went
+ off-road. Shape: (n_samples, n_objects, n_steps).
+ """
+ object_id: tf.Tensor
+ valid: tf.Tensor
+ average_displacement_error: tf.Tensor
+ linear_speed: tf.Tensor
+ linear_acceleration: tf.Tensor
+ angular_speed: tf.Tensor
+ angular_acceleration: tf.Tensor
+ distance_to_nearest_object: tf.Tensor
+ collision_per_step: tf.Tensor
+ time_to_collision: tf.Tensor
+ distance_to_road_edge: tf.Tensor
+ offroad_per_step: tf.Tensor
+
+def joint_scene_to_trajectories(
+ joint_scene: sim_agents_submission_pb2.JointScene,
+ scenario: scenario_pb2.Scenario,
+ use_log_validity: bool = False,
+ validity_mask: tf.Tensor | None = None,
+ pad_z: bool = False,
+) -> trajectory_utils.ObjectTrajectories:
+ """Converts a JointScene and the relative Scenario into `ObjectTrajectories`.
+
+ Args:
+ joint_scene: A JointScene representing either logged or simulated data,
+ corresponding to the same scenario ID as the provided logged `scenario`.
+ scenario: The original scenario proto, used to infer static attributes (i.e.
+ object types and box dimensions) from the last step of history
+ (`CURRENT_TIME_INDEX` when 0-indexed). The history steps from this
+ scenario are also prepended to the returned `Trajectories`, resulting in a
+ total length of `submission_specs.N_FULL_SCENARIO_STEPS`.
+ use_log_validity: If True, copies the validity mask from the original
+ scenario instead of assuming all the steps are valid. This is used to
+ compute features for the logged scenario.
+
+ Returns:
+ An `ObjectTrajectories` containing the trajectories of all simulated objects
+ in a scenario, with prepended history steps and inferred static dimensions
+ and object types.
+ """
+ logged_trajectories_full = trajectory_utils.ObjectTrajectories.from_scenario(
+ scenario
+ )
+ logged_trajectories_history = logged_trajectories_full.slice_time(
+ start_index=0, end_index=submission_specs.CURRENT_TIME_INDEX + 1
+ )
+
+ # Extract states and object IDs from the simulated scene.
+ sim_ids, sim_x, sim_y, sim_z, sim_heading = [], [], [], [], []
+ for simulated_trajectory in joint_scene.simulated_trajectories:
+ sim_x.append(simulated_trajectory.center_x)
+ sim_y.append(simulated_trajectory.center_y)
+ sim_z.append(simulated_trajectory.center_z)
+ sim_heading.append(simulated_trajectory.heading)
+ sim_ids.append(simulated_trajectory.object_id)
+ # Convert to tensors.
+ sim_x, sim_y, sim_z, sim_heading, sim_ids = map(
+ tf.convert_to_tensor, [sim_x, sim_y, sim_z, sim_heading, sim_ids])
+
+ # Align objects from the logged scenario to the simulated one.
+ logged_trajectories_history = (
+ logged_trajectories_history.gather_objects_by_id(sim_ids))
+ # Prepare the missing tensors: validity and box sizes.
+ if use_log_validity:
+ # When copying validity from the log, make sure objects are in the same
+ # order as `sim_ids`.
+ logged_trajectories_full = logged_trajectories_full.gather_objects_by_id(
+ sim_ids)
+ logged_trajectories_future = logged_trajectories_full.slice_time(
+ start_index=submission_specs.CURRENT_TIME_INDEX + 1
+ )
+ sim_valid = logged_trajectories_future.valid
+ elif validity_mask is not None:
+ sim_valid = validity_mask
+ else:
+ sim_valid = tf.fill(sim_x.shape, True)
+
+ sim_length = tf.repeat(
+ logged_trajectories_history.length[:, -1, tf.newaxis],
+ sim_x.shape[-1],
+ axis=-1,
+ )
+ sim_width = tf.repeat(
+ logged_trajectories_history.width[:, -1, tf.newaxis],
+ sim_x.shape[-1],
+ axis=-1,
+ )
+ sim_height = tf.repeat(
+ logged_trajectories_history.height[:, -1, tf.newaxis],
+ sim_x.shape[-1],
+ axis=-1,
+ )
+ if pad_z:
+ sim_z = tf.repeat(
+ tf.expand_dims(logged_trajectories_history.z[:, -1], axis=-1),
+ sim_x.shape[-1],
+ axis=-1,
+ )
+ # Concatenate history and logged/simulated future.
+ return trajectory_utils.ObjectTrajectories(
+ x=tf.concat([logged_trajectories_history.x, sim_x], axis=-1),
+ y=tf.concat([logged_trajectories_history.y, sim_y], axis=-1),
+ z=tf.concat([logged_trajectories_history.z, sim_z], axis=-1),
+ heading=tf.concat(
+ [logged_trajectories_history.heading, sim_heading], axis=-1
+ ),
+ length=tf.concat(
+ [logged_trajectories_history.length, sim_length], axis=-1
+ ),
+ width=tf.concat([logged_trajectories_history.width, sim_width], axis=-1),
+ height=tf.concat(
+ [logged_trajectories_history.height, sim_height], axis=-1
+ ),
+ valid=tf.concat([logged_trajectories_history.valid, sim_valid], axis=-1),
+ object_id=sim_ids,
+ object_type=logged_trajectories_history.object_type,
+ )
+
+def compute_metric_features(
+ scenario: scenario_pb2.Scenario,
+ joint_scene: sim_agents_submission_pb2.JointScene,
+ use_log_validity: bool = False,
+ validity_mask: tf.Tensor | None = None,
+ eval_agent_ids: tf.Tensor | None = None,
+) -> MetricFeatures:
+ """Computes features for a single scene.
+
+ Args:
+ scenario: The `Scenario` loaded from WOMD.
+ joint_scene: Single sample of the predicted scene starting from scenario's
+ initial conditions.
+ use_log_validity: If True, copies the validity mask from the original
+ scenario instead of assuming all the steps are valid. This is used to
+ compute features for the logged scenario.
+
+ Returns:
+ A `MetricFeatures` containing all the features.
+ """
+ # Extract `ObjectTrajectories` object from the joint scene, prepending the
+ # history from the original scenario. These composite trajectories are used to
+ # compute dynamics features, which require a few steps of context.
+ simulated_trajectories = joint_scene_to_trajectories(
+ joint_scene, scenario,
+ use_log_validity=use_log_validity,
+ validity_mask=validity_mask,
+ pad_z= (not use_log_validity),
+ )
+
+ # print(simulated_trajectories.object_id)
+ # Extract `ObjectTrajectories` from the original scenario, used for
+ # log-comparison metrics (i.e. displacement error). These also need to be
+ # aligned to the simulated trajectories.
+ logged_trajectories = trajectory_utils.ObjectTrajectories.from_scenario(
+ scenario)
+ logged_trajectories = logged_trajectories.gather_objects_by_id(
+ simulated_trajectories.object_id)
+ # From the simulated trajectories, just select the subset of objects that
+ # needs evaluation.
+ if eval_agent_ids is None:
+ evaluated_sim_agent_ids = tf.convert_to_tensor(
+ submission_specs.get_evaluation_sim_agent_ids(scenario)
+ )
+ else:
+ evaluated_sim_agent_ids = eval_agent_ids
+
+ object_ids_available = simulated_trajectories.object_id
+
+ # print("Before", evaluated_sim_agent_ids)
+ # Remove ids in the evaluated_sim_agent_ids that are not in the object_ids_available
+ evaluated_sim_agent_ids = tf.boolean_mask(
+ evaluated_sim_agent_ids,
+ tf.reduce_any(
+ evaluated_sim_agent_ids[:, tf.newaxis] == object_ids_available,
+ axis=1,
+ ),
+ )
+ # print("After", evaluated_sim_agent_ids)
+
+ # Ensure that all id are included in
+ evaluated_trajectories = simulated_trajectories.gather_objects_by_id(
+ evaluated_sim_agent_ids
+ )
+
+ # Re-order simulated trajectories, so that evaluated objects appear first,
+ # in a particular order.
+ non_evaluated_sim_agent_ids = set(
+ simulated_trajectories.object_id.numpy()
+ ) - set(evaluated_sim_agent_ids.numpy())
+ reordered_all_simulated_agent_ids = tf.constant(
+ list(evaluated_sim_agent_ids.numpy()) + list(non_evaluated_sim_agent_ids)
+ )
+ simulated_trajectories = simulated_trajectories.gather_objects_by_id(
+ reordered_all_simulated_agent_ids
+ )
+ # Prune logged trajectories to those that will be evaluated.
+ evaluated_logged_trajectories = logged_trajectories.gather_objects_by_id(
+ evaluated_sim_agent_ids
+ )
+
+ # Validity bit mask.
+ if use_log_validity:
+ validity_mask = evaluated_logged_trajectories.valid
+ else:
+ validity_mask = evaluated_trajectories.valid
+ # Slice in time to reduce to `submission_specs.N_SIMULATION_STEPS` steps.
+ validity_mask = validity_mask[:, submission_specs.CURRENT_TIME_INDEX+1:]
+
+ # Average displacement error (ADE) in 3D. Before averaging over time, the
+ # invalid states in the log need to be properly handled.
+
+ displacement_error = trajectory_features.compute_displacement_error(
+ evaluated_trajectories.x, evaluated_trajectories.y,
+ evaluated_trajectories.z, evaluated_logged_trajectories.x,
+ evaluated_logged_trajectories.y, evaluated_logged_trajectories.z)
+
+ valid_ade_steps = evaluated_logged_trajectories.valid & evaluated_trajectories.valid
+
+ object_valid_steps = tf.reduce_sum(
+ tf.cast(valid_ade_steps, tf.float32), axis=1)
+ ade = tf.reduce_sum(
+ tf.where(valid_ade_steps, displacement_error, 0.0),
+ axis=1) / object_valid_steps
+
+ # Kinematics-related features, i.e. speed and acceleration, both linear and
+ # angular. These feature are computed as finite differences of the objects
+ # position, which makes the first step invalid. We prepend the history steps
+ # so that this first simulation step has a valid difference too.
+ linear_speed, linear_accel, angular_speed, angular_accel = (
+ trajectory_features.compute_kinematic_features(
+ evaluated_trajectories.x,
+ evaluated_trajectories.y,
+ evaluated_trajectories.z,
+ evaluated_trajectories.heading,
+ seconds_per_step=submission_specs.STEP_DURATION_SECONDS))
+ # Removes the data corresponding to the history time interval.
+ linear_speed, linear_accel, angular_speed, angular_accel = (
+ map(lambda t: t[:, submission_specs.CURRENT_TIME_INDEX+1:],
+ [linear_speed, linear_accel, angular_speed, angular_accel])
+ )
+
+ # Collision and distances to objects.
+ evaluated_object_mask = tf.reduce_any(
+ # `evaluated_sim_agents` shape: (n_evaluated_objects,).
+ # `simulated_trajectories.object_id` shape: (n_objects,).
+ evaluated_sim_agent_ids[:, tf.newaxis]
+ == simulated_trajectories.object_id,
+ axis=0,
+ )
+ # Interactive features are computed between all simulated objects, but only
+ # scored for evaluated objects.
+ distances_to_objects = (
+ interaction_features.compute_distance_to_nearest_object(
+ center_x=simulated_trajectories.x,
+ center_y=simulated_trajectories.y,
+ center_z=simulated_trajectories.z,
+ length=simulated_trajectories.length,
+ width=simulated_trajectories.width,
+ height=simulated_trajectories.height,
+ heading=simulated_trajectories.heading,
+ valid=simulated_trajectories.valid,
+ evaluated_object_mask=evaluated_object_mask
+ ))
+ # Slice in time, as `simulated_trajectories` also include the history steps.
+ distances_to_objects = (
+ distances_to_objects[:, submission_specs.CURRENT_TIME_INDEX+1:])
+ # Shape: (n_evaluated_objects, n_steps).
+ is_colliding_per_step = tf.less(
+ distances_to_objects, interaction_features.COLLISION_DISTANCE_THRESHOLD)
+
+ times_to_collision = (
+ interaction_features.compute_time_to_collision_with_object_in_front(
+ center_x=simulated_trajectories.x,
+ center_y=simulated_trajectories.y,
+ length=simulated_trajectories.length,
+ width=simulated_trajectories.width,
+ heading=simulated_trajectories.heading,
+ valid=simulated_trajectories.valid,
+ evaluated_object_mask=evaluated_object_mask,
+ seconds_per_step=submission_specs.STEP_DURATION_SECONDS,
+ )
+ )
+ times_to_collision = times_to_collision[
+ :, submission_specs.CURRENT_TIME_INDEX + 1 :
+ ]
+
+ # Roadgraph features.
+ road_edges = []
+ for map_feature in scenario.map_features:
+ if map_feature.HasField('road_edge'):
+ road_edges.append(map_feature.road_edge.polyline)
+ distances_to_road_edge = map_metric_features.compute_distance_to_road_edge(
+ center_x=simulated_trajectories.x,
+ center_y=simulated_trajectories.y,
+ center_z=simulated_trajectories.z,
+ length=simulated_trajectories.length,
+ width=simulated_trajectories.width,
+ height=simulated_trajectories.height,
+ heading=simulated_trajectories.heading,
+ valid=simulated_trajectories.valid,
+ evaluated_object_mask=evaluated_object_mask,
+ road_edge_polylines=road_edges,
+ )
+ distances_to_road_edge = distances_to_road_edge[
+ :, submission_specs.CURRENT_TIME_INDEX + 1 :
+ ]
+ is_offroad_per_step = tf.greater(
+ distances_to_road_edge, map_metric_features.OFFROAD_DISTANCE_THRESHOLD
+ )
+
+ # Pack into `MetricFeatures`, also adding a batch dimension of 1 (except for
+ # `object_id`).
+ return MetricFeatures(
+ object_id=evaluated_trajectories.object_id,
+ valid=validity_mask[tf.newaxis],
+ average_displacement_error=ade[tf.newaxis],
+ linear_speed=linear_speed[tf.newaxis],
+ linear_acceleration=linear_accel[tf.newaxis],
+ angular_speed=angular_speed[tf.newaxis],
+ angular_acceleration=angular_accel[tf.newaxis],
+ distance_to_nearest_object=distances_to_objects[tf.newaxis],
+ collision_per_step=is_colliding_per_step[tf.newaxis],
+ time_to_collision=times_to_collision[tf.newaxis],
+ distance_to_road_edge=distances_to_road_edge[tf.newaxis],
+ offroad_per_step=is_offroad_per_step[tf.newaxis],
+ )
+
+
+def compute_scenario_rollouts_features(
+ scenario: scenario_pb2.Scenario,
+ scenario_rollouts: sim_agents_submission_pb2.ScenarioRollouts,
+ scenario_rollouts_mask: tf.Tensor | None = None,
+) -> tuple[MetricFeatures, MetricFeatures]:
+ """Computes the metrics features for both logged and simulated scenarios.
+
+ Args:
+ scenario: The `Scenario` loaded from WOMD.
+ scenario_rollouts: The collection of joint scenes from simulation.
+
+ Returns:
+ Two `MetricFeatures`, the first one from logged data with n_samples=1 and
+ the second from simulation with n_samples=`submission_specs.N_ROLLOUTS`.
+ """
+
+ # print("Sim")
+ # Aggregate the different parallel simulations.
+ features_fields = [field.name for field in dataclasses.fields(MetricFeatures)]
+ features_fields.remove('object_id')
+ sim_features = collections.defaultdict(list)
+ for joint_scene in scenario_rollouts.joint_scenes:
+ rollout_features = compute_metric_features(scenario, joint_scene, validity_mask=scenario_rollouts_mask)
+ # if tf.reduce_any(log_features.object_id != rollout_features.object_id):
+ # raise ValueError('Misaligned object IDs for evaluation.')
+ for field in features_fields:
+ sim_features[field].append(getattr(rollout_features, field))
+
+ # Concatenate and generate `MetricFeatures`.
+ for field in features_fields:
+ sim_features[field] = tf.concat(sim_features[field], axis=0)
+ # print("Log")
+ log_joint_scene = converters.scenario_to_joint_scene(scenario)
+ log_features = compute_metric_features(
+ scenario, log_joint_scene, use_log_validity=True,
+ eval_agent_ids=rollout_features.object_id
+ )
+
+ sim_features = MetricFeatures(
+ **sim_features, object_id=log_features.object_id)
+ return log_features, sim_features
diff --git a/examples/eval/wosac_metrics/metrics.py b/examples/eval/wosac_metrics/metrics.py
new file mode 100644
index 000000000..04cf404ab
--- /dev/null
+++ b/examples/eval/wosac_metrics/metrics.py
@@ -0,0 +1,321 @@
+# Copyright (c) 2024 Waymo LLC. All rights reserved.
+
+# This is licensed under a BSD+Patent license.
+# Please see LICENSE and PATENTS text files.
+# ==============================================================================
+"""Collection of metrics used to evaluate Sim Agents Challenge submissions."""
+
+from typing import List
+
+from google.protobuf import text_format
+import numpy as np
+import tensorflow as tf
+
+# copybara removed file resource import
+import waymo_open_dataset
+from waymo_open_dataset.protos import scenario_pb2
+from waymo_open_dataset.protos import sim_agents_metrics_pb2
+from waymo_open_dataset.protos import sim_agents_submission_pb2
+from waymo_open_dataset.wdl_limited.sim_agents_metrics import estimators
+
+import sys
+import os
+
+sys.path.append('examples/eval/wosac_metrics')
+import metric_features
+
+# from waymo_open_dataset.wdl_limited.sim_agents_metrics import metric_features
+from waymo_open_dataset.wdl_limited.sim_agents_metrics import trajectory_features
+
+_METRIC_FIELD_NAMES_BY_BUCKET = {
+ 'kinematic': [
+ 'linear_speed', 'linear_acceleration',
+ 'angular_speed', 'angular_acceleration',
+ ],
+ 'interactive': [
+ 'distance_to_nearest_object', 'collision_indication',
+ 'time_to_collision',
+ ],
+ 'map_based': [
+ 'distance_to_road_edge', 'offroad_indication'
+ ]
+}
+_METRIC_FIELD_NAMES = (
+ _METRIC_FIELD_NAMES_BY_BUCKET['kinematic'] +
+ _METRIC_FIELD_NAMES_BY_BUCKET['interactive'] +
+ _METRIC_FIELD_NAMES_BY_BUCKET['map_based']
+)
+
+
+def load_metrics_config() -> sim_agents_metrics_pb2.SimAgentMetricsConfig:
+ """Loads the `SimAgentMetricsConfig` used for the challenge."""
+ # pylint: disable=line-too-long
+ # pyformat: disable
+ config_path = '{pyglib_resource}/wdl_limited/sim_agents_metrics/challenge_2024_config.textproto'.format(
+ pyglib_resource=waymo_open_dataset.__path__[0]
+ )
+ with open(config_path, 'r') as f:
+ config = sim_agents_metrics_pb2.SimAgentMetricsConfig()
+ text_format.Parse(f.read(), config)
+ return config
+
+
+def compute_scenario_metrics_for_bundle(
+ config: sim_agents_metrics_pb2.SimAgentMetricsConfig,
+ scenario: scenario_pb2.Scenario,
+ scenario_rollouts: sim_agents_submission_pb2.ScenarioRollouts,
+ scenario_rollouts_mask: tf.Tensor = None,
+) -> sim_agents_metrics_pb2.SimAgentMetrics:
+ """Computes the scenario-level metrics for the given bundle."""
+ # Computes the metric features for log and sim.
+ log_features, sim_features = (
+ metric_features.compute_scenario_rollouts_features(
+ scenario, scenario_rollouts, scenario_rollouts_mask=scenario_rollouts_mask)
+ )
+
+ # ==== Average Displacement Error ====
+ # This metric is not included in the scoring meta-metric, but we report it
+ # to have a baseline comparison with existing Behaviour Prediction challenges.
+ # We report both ADE (averaged over simulations and objects) and minADE
+ # (averaged over objects, minimum over simulations).
+ average_displacement_error = tf.reduce_mean(
+ sim_features.average_displacement_error)
+ min_average_displacement_error = tf.reduce_min(
+ tf.reduce_mean(sim_features.average_displacement_error, axis=1))
+
+ # ==== Dynamics features ====
+ # Compute the log-likelihoods of speed features (first derivatives).
+ # Note: For log_values we take only index=0 of the batch dimension to have
+ # shape (n_objects, n_steps), as specified by
+ # `log_likelihood_estimate_timeseries()`.
+ linear_speed_log_likelihood = estimators.log_likelihood_estimate_timeseries(
+ feature_config=config.linear_speed,
+ log_values=log_features.linear_speed[0],
+ sim_values=sim_features.linear_speed)
+ angular_speed_log_likelihood = estimators.log_likelihood_estimate_timeseries(
+ feature_config=config.angular_speed,
+ log_values=log_features.angular_speed[0],
+ sim_values=sim_features.angular_speed)
+ # Get the log speed (linear and angular) validity. Since this is computed by
+ # a delta between steps `i-1` and `i+1`, we verify that both of these are
+ # valid (logical and).
+ speed_validity, acceleration_validity = (
+ trajectory_features.compute_kinematic_validity(log_features.valid[0])
+ )
+ # The score is computed as the sum of the log-likelihoods, filtered by
+ # validity. We exponentiate the result to get a score in the range [0,1].
+ linear_speed_likelihood = tf.exp(_reduce_average_with_validity(
+ linear_speed_log_likelihood, speed_validity))
+ angular_speed_likelihood = tf.exp(_reduce_average_with_validity(
+ angular_speed_log_likelihood, speed_validity))
+
+ # Similarly, we compute likelihoods for acceleration features. This time,
+ # we have to compute a double-step validity mask, because accelerations
+ # involve the validity of `i`, `i+1`, `i+2`.
+ linear_accel_log_likelihood = estimators.log_likelihood_estimate_timeseries(
+ feature_config=config.linear_acceleration,
+ log_values=log_features.linear_acceleration[0],
+ sim_values=sim_features.linear_acceleration)
+ angular_accel_log_likelihood = estimators.log_likelihood_estimate_timeseries(
+ feature_config=config.angular_acceleration,
+ log_values=log_features.angular_acceleration[0],
+ sim_values=sim_features.angular_acceleration)
+ linear_accel_likelihood = tf.exp(_reduce_average_with_validity(
+ linear_accel_log_likelihood, acceleration_validity))
+ angular_accel_likelihood = tf.exp(_reduce_average_with_validity(
+ angular_accel_log_likelihood, acceleration_validity))
+
+ # Collision likelihood is computed by aggregating in time. For invalid objects
+ # in the logged scenario, we need to filter possible collisions in simulation.
+ # `sim_collision_indication` shape: (n_samples, n_objects).
+ sim_collision_indication = tf.reduce_any(
+ tf.where(log_features.valid, sim_features.collision_per_step, False),
+ axis=2)
+ log_collision_indication = tf.reduce_any(
+ tf.where(log_features.valid, log_features.collision_per_step, False),
+ axis=2)
+
+ # Collision and distance to other objects. Again, aggregate over objects and
+ # timesteps by summing the log-probabilities.
+ collision_score = estimators.log_likelihood_estimate_scenario_level(
+ feature_config=config.collision_indication,
+ log_values=log_collision_indication[0],
+ sim_values=sim_collision_indication
+ )
+ collision_likelihood = tf.exp(tf.reduce_mean(collision_score))
+
+ distance_to_objects_log_likelihood = (
+ estimators.log_likelihood_estimate_timeseries(
+ feature_config=config.distance_to_nearest_object,
+ log_values=log_features.distance_to_nearest_object[0],
+ sim_values=sim_features.distance_to_nearest_object,
+ )
+ )
+ distance_to_obj_likelihood = tf.exp(
+ _reduce_average_with_validity(
+ distance_to_objects_log_likelihood, log_features.valid[0]
+ )
+ )
+
+ ttc_log_likelihood = estimators.log_likelihood_estimate_timeseries(
+ feature_config=config.time_to_collision,
+ log_values=log_features.time_to_collision[0],
+ sim_values=sim_features.time_to_collision,
+ )
+ ttc_likelihood = tf.exp(
+ _reduce_average_with_validity(ttc_log_likelihood, log_features.valid[0])
+ )
+
+ # Off-road and distance to road edge. Again, aggregate over objects and
+ # timesteps by summing the log-probabilities.
+ # `sim_offroad_indication` shape: (n_samples, n_objects).
+ sim_offroad_indication = tf.reduce_any(
+ tf.where(log_features.valid, sim_features.offroad_per_step, False),
+ axis=2)
+ log_offroad_indication = tf.reduce_any(
+ tf.where(log_features.valid, log_features.offroad_per_step, False),
+ axis=2)
+ offroad_score = estimators.log_likelihood_estimate_scenario_level(
+ feature_config=config.offroad_indication,
+ log_values=log_offroad_indication[0],
+ sim_values=sim_offroad_indication,
+ )
+ offroad_likelihood = tf.exp(tf.reduce_mean(offroad_score))
+
+ # `distance_to_road_edge_log_likelihood` shape: (n_objects, n_steps).
+ distance_to_road_edge_log_likelihood = (
+ estimators.log_likelihood_estimate_timeseries(
+ feature_config=config.distance_to_road_edge,
+ log_values=log_features.distance_to_road_edge[0],
+ sim_values=sim_features.distance_to_road_edge,
+ )
+ )
+ distance_to_road_edge_likelihood = tf.exp(
+ _reduce_average_with_validity(
+ distance_to_road_edge_log_likelihood, log_features.valid[0]
+ )
+ )
+
+ # ==== Simulated collision and offroad rates ====
+ simulated_collision_rate = tf.reduce_sum(
+ # `sim_collision_indication` shape: (n_samples, n_objects).
+ tf.cast(sim_collision_indication, tf.int32)
+ ) / tf.reduce_sum(tf.ones_like(sim_collision_indication, dtype=tf.int32))
+ simulated_offroad_rate = tf.reduce_sum(
+ # `sim_offroad_indication` shape: (n_samples, n_objects).
+ tf.cast(sim_offroad_indication, tf.int32)
+ ) / tf.reduce_sum(tf.ones_like(sim_offroad_indication, dtype=tf.int32))
+
+ # ==== Meta-metric ====
+ likelihood_metrics = {
+ 'linear_speed_likelihood': linear_speed_likelihood.numpy(),
+ 'linear_acceleration_likelihood': linear_accel_likelihood.numpy(),
+ 'angular_speed_likelihood': angular_speed_likelihood.numpy(),
+ 'angular_acceleration_likelihood': angular_accel_likelihood.numpy(),
+ 'distance_to_nearest_object_likelihood': (
+ distance_to_obj_likelihood.numpy()
+ ),
+ 'collision_indication_likelihood': collision_likelihood.numpy(),
+ 'time_to_collision_likelihood': ttc_likelihood.numpy(),
+ 'distance_to_road_edge_likelihood': (
+ distance_to_road_edge_likelihood.numpy()
+ ),
+ 'offroad_indication_likelihood': offroad_likelihood.numpy(),
+ }
+
+ metametric = _compute_metametric(
+ config, sim_agents_metrics_pb2.SimAgentMetrics(**likelihood_metrics))
+
+ return sim_agents_metrics_pb2.SimAgentMetrics(
+ scenario_id=scenario.scenario_id,
+ metametric=metametric,
+ average_displacement_error=average_displacement_error,
+ min_average_displacement_error=min_average_displacement_error,
+ simulated_collision_rate=simulated_collision_rate.numpy(),
+ simulated_offroad_rate=simulated_offroad_rate.numpy(),
+ **likelihood_metrics,
+ )
+
+
+def aggregate_scenario_metrics(
+ all_scenario_metrics: List[sim_agents_metrics_pb2.SimAgentMetrics]
+ ) -> sim_agents_metrics_pb2.SimAgentMetrics:
+ """Aggregates the per-scenario metrics over the whole dataset."""
+ msg_fields = [field[0].name for field in all_scenario_metrics[0].ListFields()]
+ field_values = {field_name: [] for field_name in msg_fields}
+ for scenario_metrics in all_scenario_metrics:
+ for field_name in msg_fields:
+ field_values[field_name].append(getattr(scenario_metrics, field_name))
+ # Remove the scenario ID field.
+ del field_values['scenario_id']
+ # Average all the fields.
+ field_values = {
+ name: np.mean(values) for (name, values) in field_values.items()}
+ return sim_agents_metrics_pb2.SimAgentMetrics(
+ **field_values)
+
+
+def aggregate_metrics_to_buckets(
+ config: sim_agents_metrics_pb2.SimAgentMetricsConfig,
+ metrics: sim_agents_metrics_pb2.SimAgentMetrics
+) -> sim_agents_metrics_pb2.SimAgentsBucketedMetrics:
+ """Aggregates metrics into buckets for better readability."""
+ bucketed_metrics = {}
+ for bucket_name, fields_in_bucket in _METRIC_FIELD_NAMES_BY_BUCKET.items():
+ weighted_metric, weights_sum = 0.0, 0.0
+ for field_name in fields_in_bucket:
+ likelihood_field_name = field_name + '_likelihood'
+ weight = getattr(config, field_name).metametric_weight
+ metric_score = getattr(metrics, likelihood_field_name)
+ weighted_metric += weight * metric_score
+ weights_sum += weight
+ if weights_sum == 0:
+ raise ValueError('The bucket\'s weight sum is zero. Check your metrics'
+ ' config.')
+ bucketed_metrics[bucket_name] = weighted_metric / weights_sum
+
+ return sim_agents_metrics_pb2.SimAgentsBucketedMetrics(
+ realism_meta_metric=metrics.metametric,
+ kinematic_metrics=bucketed_metrics['kinematic'],
+ interactive_metrics=bucketed_metrics['interactive'],
+ map_based_metrics=bucketed_metrics['map_based'],
+ min_ade=metrics.min_average_displacement_error,
+ simulated_collision_rate=metrics.simulated_collision_rate,
+ simulated_offroad_rate=metrics.simulated_offroad_rate,
+ )
+
+
+def _reduce_average_with_validity(
+ tensor: tf.Tensor, validity: tf.Tensor) -> tf.Tensor:
+ """Returns the tensor's average, only selecting valid items.
+
+ Args:
+ tensor: A float tensor of any shape.
+ validity: A boolean tensor of the same shape as `tensor`.
+
+ Returns:
+ A float tensor of shape (1,), containing the average of the valid elements
+ of `tensor`.
+ """
+ if tensor.shape != validity.shape:
+ raise ValueError('Shapes of `tensor` and `validity` must be the same.'
+ f'(Actual: {tensor.shape}, {validity.shape}).')
+ cond_sum = tf.reduce_sum(tf.where(validity, tensor, tf.zeros_like(tensor)))
+ valid_sum = tf.reduce_sum(tf.cast(validity, tf.float32))
+ return cond_sum / valid_sum
+
+
+def _compute_metametric(
+ config: sim_agents_metrics_pb2.SimAgentMetricsConfig,
+ metrics: sim_agents_metrics_pb2.SimAgentMetrics,
+):
+ """Computes the meta-metric aggregation."""
+ metametric = 0.0
+ for field_name in _METRIC_FIELD_NAMES:
+ likelihood_field_name = field_name + '_likelihood'
+ weight = getattr(config, field_name).metametric_weight
+ metric_score = getattr(metrics, likelihood_field_name)
+ metametric += weight * metric_score
+ return metametric
+
+
diff --git a/gpudrive/env/env_torch.py b/gpudrive/env/env_torch.py
index f57b378f7..bab31dc72 100755
--- a/gpudrive/env/env_torch.py
+++ b/gpudrive/env/env_torch.py
@@ -91,11 +91,10 @@ def __init__(
self.num_worlds,
self.max_agent_count,
backend=self.backend,
+ device=self.device,
)
self.episode_len = self.config.episode_len
- self.reference_path_length = (
- self.log_trajectory.pos_xy.shape[2] - self.config.init_steps
- )
+ self.reference_path_length = self.log_trajectory.pos_xy.shape[2]
self.step_in_world = (
self.episode_len - self.sim.steps_remaining_tensor().to_torch()
)
@@ -873,7 +872,7 @@ def _get_ego_state(self, mask=None) -> torch.Tensor:
if self.config.add_reference_speed:
avg_ref_speed = (
- self.log_trajectory.clone().ref_speed.mean(axis=-1)
+ self.log_trajectory.ref_speed.clone().mean(axis=-1)
/ constants.MAX_SPEED
)
@@ -1598,6 +1597,7 @@ def swap_data_batch(self, data_batch=None):
self.num_worlds,
self.max_agent_count,
backend=self.backend,
+ device=self.device,
)
def _load_vbd_trajectories(self):
@@ -1754,7 +1754,7 @@ def get_scenario_ids(self):
print(highlight_agent)
- for t in range(10):
+ for t in range(90):
print(f"Step: {t+1}")
# Step the environment
diff --git a/gpudrive/integrations/puffer/ppo.py b/gpudrive/integrations/puffer/ppo.py
index fa5a961fd..3bf2ab1f9 100644
--- a/gpudrive/integrations/puffer/ppo.py
+++ b/gpudrive/integrations/puffer/ppo.py
@@ -723,7 +723,7 @@ def save_checkpoint(data, save_checkpoint_to_wandb=True):
"action_dim": data.uncompiled_policy.action_dim,
"exp_id": config.exp_id,
"num_params": config.network["num_parameters"],
- "config": config,
+ "config": data.policy.config,
}
torch.save(state, model_path)
diff --git a/gpudrive/networks/late_fusion.py b/gpudrive/networks/late_fusion.py
index 504c78187..dee9bf51a 100644
--- a/gpudrive/networks/late_fusion.py
+++ b/gpudrive/networks/late_fusion.py
@@ -82,7 +82,8 @@ def __init__(
act_func="tanh",
max_controlled_agents=64,
obs_dim=2984, # Size of the flattened observation vector (hardcoded)
- config=None, # Optional config
+ config=None, # Optional config,
+ **kwargs,
):
super().__init__()
self.input_dim = input_dim
diff --git a/gpudrive/utils/checkpoint.py b/gpudrive/utils/checkpoint.py
index 43c2215e3..cc76a1f20 100644
--- a/gpudrive/utils/checkpoint.py
+++ b/gpudrive/utils/checkpoint.py
@@ -1,6 +1,7 @@
import torch
from gpudrive.networks.late_fusion import NeuralNet
+from gpudrive.networks.agents import Agent
def load_policy(path_to_cpt, model_name, device, env_config=None):
@@ -27,3 +28,32 @@ def load_policy(path_to_cpt, model_name, device, env_config=None):
policy.load_state_dict(saved_cpt["parameters"])
return policy.eval()
+
+
+def load_agent(path_to_cpt):
+ """
+ Load a trained agent from checkpoint file and return it in evaluation mode.
+
+ Args:
+ path_to_cpt: Path to the checkpoint file (.pt)
+
+ Returns:
+ The loaded agent model set to evaluation mode
+ """
+ # Load .pt checkpoint file
+ saved_cpt = torch.load(
+ f=path_to_cpt,
+ weights_only=False,
+ )
+
+ # Create policy architecture from saved checkpoint
+ agent = Agent(
+ config=saved_cpt["config"],
+ embed_dim=saved_cpt["model_arch"]["embed_dim"],
+ action_dim=saved_cpt["action_dim"],
+ )
+
+ # Load the model parameters
+ agent.load_state_dict(saved_cpt["parameters"])
+
+ return agent.eval()
diff --git a/pyproject.toml b/pyproject.toml
index c4894679e..383e9718b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -22,7 +22,7 @@ readme = "README.md"
description = "A GPU-accelerated, multi-agent driving simulator"
requires-python = ">=3.11"
dependencies = [
- "numpy>=1.26.4",
+ "numpy>=1.23.0",
"gymnasium",
"pygame",
"matplotlib==3.9",
diff --git a/src/level_gen.cpp b/src/level_gen.cpp
index 87549e52f..ef171ea54 100755
--- a/src/level_gen.cpp
+++ b/src/level_gen.cpp
@@ -113,10 +113,15 @@ static inline void populateVBDTrajectory(Engine &ctx, const Entity &agent, const
static inline bool isAgentStatic(Engine &ctx, Entity agent) {
auto agent_iface = ctx.get(agent).e;
-
- // Static agents are those that are not tracks to predict
- if (ctx.data().params.readFromTracksToPredict and ctx.get(agent_iface).isTrackToPredict != -1) {
- return false;
+
+ // Static agents are those that are not tracks to predict
+ if (ctx.data().params.readFromTracksToPredict) {
+ if (ctx.get(agent_iface).isTrackToPredict == -1) {
+ return true;
+ }
+ else {
+ return false;
+ }
}
// Original logic for other initialization modes