|
import os |
|
|
|
import pandas as pd |
|
from socceraction.data.wyscout import PublicWyscoutLoader |
|
from socceraction.spadl import SPADLSchema |
|
from socceraction.spadl import config as spadl |
|
from socceraction.spadl import wyscout as wy |
|
|
|
|
|
class TestSpadlConvertor: |
|
def setup_method(self) -> None: |
|
data_dir = os.path.join( |
|
os.path.dirname(__file__), os.pardir, "datasets", "wyscout_public", "raw" |
|
) |
|
self.WSL = PublicWyscoutLoader(root=data_dir, download=False) |
|
self.events = self.WSL.events(2058007) |
|
|
|
def test_convert_to_actions(self) -> None: |
|
df_actions = wy.convert_to_actions(self.events, 5629) |
|
assert len(df_actions) > 0 |
|
SPADLSchema.validate(df_actions) |
|
assert (df_actions.game_id == 2058007).all() |
|
assert ((df_actions.team_id == 5629) | (df_actions.team_id == 12913)).all() |
|
|
|
def test_insert_interception_passes(self) -> None: |
|
event = pd.DataFrame( |
|
[ |
|
{ |
|
"type_id": 8, |
|
"subtype_name": "Head pass", |
|
"tags": [{"id": 102}, {"id": 1401}, {"id": 1801}], |
|
"player_id": 38093, |
|
"positions": [{"y": 56, "x": 5}, {"y": 100, "x": 100}], |
|
"game_id": 2499737, |
|
"type_name": "Pass", |
|
"team_id": 1610, |
|
"period_id": 2, |
|
"milliseconds": 2184.793924, |
|
"subtype_id": 82, |
|
"event_id": 180427412, |
|
} |
|
] |
|
) |
|
actions = wy.convert_to_actions(event, 1610) |
|
assert len(actions) == 2 |
|
assert actions.at[0, "type_id"] == spadl.actiontypes.index("interception") |
|
assert actions.at[1, "type_id"] == spadl.actiontypes.index("bad_touch") |
|
assert actions.at[0, "result_id"] == spadl.results.index("success") |
|
assert actions.at[1, "result_id"] == spadl.results.index("owngoal") |
|
|
|
def test_convert_own_goal(self) -> None: |
|
events_morira = self.WSL.events(2057961) |
|
own_goal_event = events_morira[events_morira.event_id == 258696133] |
|
own_goal_actions = wy.convert_to_actions(own_goal_event, 16216) |
|
assert len(own_goal_actions) == 2 |
|
assert own_goal_actions.iloc[0]["type_id"] == spadl.actiontypes.index("interception") |
|
assert own_goal_actions.iloc[0]["result_id"] == spadl.results.index("success") |
|
assert own_goal_actions.iloc[1]["type_id"] == spadl.actiontypes.index("bad_touch") |
|
assert own_goal_actions.iloc[1]["result_id"] == spadl.results.index("owngoal") |
|
assert own_goal_actions.iloc[1]["bodypart_id"] == spadl.bodyparts.index("foot") |
|
|
|
def test_convert_own_goal_touches(self) -> None: |
|
"""Tests conversion of own goals following a bad touch. |
|
|
|
Own goals resulting from bad touch events in the Wyscout event |
|
streams should be included in the SPADL representation. |
|
""" |
|
|
|
|
|
|
|
event = pd.DataFrame( |
|
[ |
|
{ |
|
"type_id": 8, |
|
"subtype_name": "Cross", |
|
"tags": [{"id": 402}, {"id": 801}, {"id": 1802}], |
|
"player_id": 8013, |
|
"positions": [{"y": 89, "x": 97}, {"y": 0, "x": 0}], |
|
"game_id": 2499994, |
|
"type_name": "Pass", |
|
"team_id": 1631, |
|
"period_id": 2, |
|
"milliseconds": 1496.7290489999993, |
|
"subtype_id": 80, |
|
"event_id": 230320305, |
|
}, |
|
{ |
|
"type_id": 7, |
|
"subtype_name": "Touch", |
|
"tags": [{"id": 102}], |
|
"player_id": 8094, |
|
"positions": [{"y": 50, "x": 1}, {"y": 100, "x": 100}], |
|
"game_id": 2499994, |
|
"type_name": "Others on the ball", |
|
"team_id": 1639, |
|
"period_id": 2, |
|
"milliseconds": 1497.6330749999993, |
|
"subtype_id": 72, |
|
"event_id": 230320132, |
|
}, |
|
{ |
|
"type_id": 9, |
|
"subtype_name": "Reflexes", |
|
"tags": [{"id": 101}, {"id": 1802}], |
|
"player_id": 8094, |
|
"positions": [{"y": 100, "x": 100}, {"y": 50, "x": 1}], |
|
"game_id": 2499994, |
|
"type_name": "Save attempt", |
|
"team_id": 1639, |
|
"period_id": 2, |
|
"milliseconds": 1499.980547, |
|
"subtype_id": 90, |
|
"event_id": 230320135, |
|
}, |
|
] |
|
) |
|
actions = wy.convert_to_actions(event, 1639) |
|
|
|
|
|
|
|
assert len(actions) == 4 |
|
assert actions.at[1, "type_id"] == spadl.actiontypes.index("bad_touch") |
|
assert actions.at[1, "result_id"] == spadl.results.index("owngoal") |
|
|
|
def test_convert_simulations_precede_by_take_on(self) -> None: |
|
events = pd.DataFrame( |
|
[ |
|
{ |
|
"type_id": 1, |
|
"subtype_name": "Ground attacking duel", |
|
"tags": [{"id": 503}, {"id": 701}, {"id": 1802}], |
|
"player_id": 8327, |
|
"positions": [{"y": 48, "x": 82}, {"y": 47, "x": 83}], |
|
"game_id": 2576263, |
|
"type_name": "Duel", |
|
"team_id": 3158, |
|
"period_id": 2, |
|
"milliseconds": 706.309475 * 1000, |
|
"subtype_id": 11, |
|
"event_id": 240828365, |
|
}, |
|
{ |
|
"type_id": 2, |
|
"subtype_name": "Simulation", |
|
"tags": [{"id": 1702}], |
|
"player_id": 8327, |
|
"positions": [{"y": 47, "x": 83}, {"y": 0, "x": 0}], |
|
"game_id": 2576263, |
|
"type_name": "Foul", |
|
"team_id": 3158, |
|
"period_id": 2, |
|
"milliseconds": 709.1020480000002 * 1000, |
|
"subtype_id": 25, |
|
"event_id": 240828368, |
|
}, |
|
] |
|
) |
|
|
|
actions = wy.convert_to_actions(events, 3158) |
|
|
|
assert len(actions) == 1 |
|
assert actions.at[0, "type_id"] == spadl.actiontypes.index("take_on") |
|
assert actions.at[0, "result_id"] == spadl.results.index("fail") |
|
|
|
def test_convert_simulations(self) -> None: |
|
events = pd.DataFrame( |
|
[ |
|
{ |
|
"type_id": 8, |
|
"subtype_name": "Cross", |
|
"tags": [{"id": 402}, {"id": 801}, {"id": 1801}], |
|
"player_id": 20472, |
|
"positions": [{"y": 76, "x": 92}, {"y": 92, "x": 98}], |
|
"game_id": 2575974, |
|
"type_name": "Pass", |
|
"team_id": 3173, |
|
"period_id": 1, |
|
"milliseconds": 1010.5460250000001 * 1000, |
|
"subtype_id": 80, |
|
"event_id": 182640540, |
|
}, |
|
{ |
|
"type_id": 1, |
|
"subtype_name": "Ground loose ball duel", |
|
"tags": [{"id": 701}, {"id": 1802}], |
|
"player_id": 116171, |
|
"positions": [{"y": 92, "x": 98}, {"y": 43, "x": 87}], |
|
"game_id": 2575974, |
|
"type_name": "Duel", |
|
"team_id": 3173, |
|
"period_id": 1, |
|
"milliseconds": 1012.8018770000001 * 1000, |
|
"subtype_id": 13, |
|
"event_id": 182640541, |
|
}, |
|
{ |
|
"type_id": 2, |
|
"subtype_name": "Simulation", |
|
"tags": [{"id": 1702}], |
|
"player_id": 116171, |
|
"positions": [{"y": 43, "x": 87}, {"y": 100, "x": 100}], |
|
"game_id": 2575974, |
|
"type_name": "Foul", |
|
"team_id": 3173, |
|
"period_id": 1, |
|
"milliseconds": 1014.7540220000001 * 1000, |
|
"subtype_id": 25, |
|
"event_id": 182640542, |
|
}, |
|
] |
|
) |
|
|
|
actions = wy.convert_to_actions(events, 3157) |
|
|
|
assert len(actions) == 3 |
|
assert actions.at[2, "type_id"] == spadl.actiontypes.index("take_on") |
|
assert actions.at[2, "result_id"] == spadl.results.index("fail") |
|
|