Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions kloppy/_providers/datafactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def load(
event_types: Optional[List[str]] = None,
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
"""
Load DataFactory event data.
Expand All @@ -21,6 +22,7 @@ def load(
event_types: A list of event types to load.
coordinates: The coordinate system to use.
event_factory: A custom event factory.
exclude_penalty_shootouts: If True, excludes events from penalty shootouts (period 5).

Returns:
The parsed event data.
Expand All @@ -29,6 +31,7 @@ def load(
event_types=event_types,
coordinate_system=coordinates,
event_factory=event_factory or get_config("event_factory"),
exclude_penalty_shootouts=exclude_penalty_shootouts,
)
with open_as_file(event_data) as event_data_fp:
return deserializer.deserialize(
Expand Down
6 changes: 6 additions & 0 deletions kloppy/_providers/impect.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def load(
event_types: Optional[List[str]] = None,
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
"""
Load Impect event data into a [`EventDataset`][kloppy.domain.models.event.EventDataset]
Expand All @@ -30,6 +31,7 @@ def load(
event_types: A list of event types to load. When set, only the specified event types will be loaded.
coordinates: The coordinate system to use. Defaults to "impect". See [`kloppy.domain.models.common.Provider`][kloppy.domain.models.common.Provider] for available options.
event_factory: A custom event factory. When set, the factory is used to create event instances.
exclude_penalty_shootouts: If True, excludes events from penalty shootouts (period 5).

Returns:
The parsed event data.
Expand All @@ -38,6 +40,7 @@ def load(
event_types=event_types,
coordinate_system=coordinates,
event_factory=event_factory or get_config("event_factory"),
exclude_penalty_shootouts=exclude_penalty_shootouts,
)
with open_as_file(event_data) as event_data_fp, open_as_file(
lineup_data
Expand All @@ -62,6 +65,7 @@ def load_open_data(
event_types: Optional[List[str]] = None,
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
"""
Load Impect open data.
Expand All @@ -75,6 +79,7 @@ def load_open_data(
event_types: A list of event types to load.
coordinates: The coordinate system to use.
event_factory: A custom event factory.
exclude_penalty_shootouts: If True, excludes events from penalty shootouts (period 5).

Returns:
The parsed event data.
Expand Down Expand Up @@ -104,4 +109,5 @@ def load_open_data(
event_types=event_types,
coordinates=coordinates,
event_factory=event_factory,
exclude_penalty_shootouts=exclude_penalty_shootouts,
)
3 changes: 3 additions & 0 deletions kloppy/_providers/metrica.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def load_event(
event_types: Optional[List[str]] = None,
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
"""Load Metrica Sports JSON event data.

Expand All @@ -100,6 +101,7 @@ def load_event(
event_types: A list of event types to load.
coordinates: The coordinate system to use.
event_factory: A custom event factory.
exclude_penalty_shootouts: If True, excludes events from penalty shootouts (period 5).

Returns:
The parsed event data.
Expand All @@ -108,6 +110,7 @@ def load_event(
event_types=event_types,
coordinate_system=coordinates,
event_factory=event_factory or get_config("event_factory"),
exclude_penalty_shootouts=exclude_penalty_shootouts,
)

with open_as_file(event_data) as event_data_fp, open_as_file(
Expand Down
3 changes: 3 additions & 0 deletions kloppy/_providers/opta.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def load(
event_types: Optional[List[str]] = None,
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
"""
Load Opta event data.
Expand All @@ -23,6 +24,7 @@ def load(
event_types: A list of event types to load.
coordinates: The coordinate system to use.
event_factory: A custom event factory.
exclude_penalty_shootouts: If True, excludes events from penalty shootouts (period 5).

Returns:
The parsed event data.
Expand All @@ -31,6 +33,7 @@ def load(
event_types=event_types,
coordinate_system=coordinates,
event_factory=event_factory or get_config("event_factory"),
exclude_penalty_shootouts=exclude_penalty_shootouts,
)
with open_as_file(f7_data) as f7_data_fp, open_as_file(
f24_data
Expand Down
14 changes: 13 additions & 1 deletion kloppy/_providers/sportec.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def load_event(
event_types: Optional[List[str]] = None,
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
"""
Load Sportec Solutions event data.
Expand All @@ -30,6 +31,7 @@ def load_event(
event_types: A list of event types to load.
coordinates: The coordinate system to use.
event_factory: A custom event factory.
exclude_penalty_shootouts: If True, excludes events from penalty shootouts (period 5).

Returns:
The parsed event data.
Expand All @@ -38,6 +40,7 @@ def load_event(
event_types=event_types,
coordinate_system=coordinates,
event_factory=event_factory or get_config("event_factory"),
exclude_penalty_shootouts=exclude_penalty_shootouts,
)
with open_as_file(event_data) as event_data_fp, open_as_file(
meta_data
Expand Down Expand Up @@ -94,9 +97,15 @@ def load(
event_types: Optional[List[str]] = None,
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
return load_event(
event_data, meta_data, event_types, coordinates, event_factory
event_data,
meta_data,
event_types,
coordinates,
event_factory,
exclude_penalty_shootouts,
)


Expand Down Expand Up @@ -133,6 +142,7 @@ def load_open_event_data(
event_types: Optional[List[str]] = None,
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
"""
Load event data for a game from the IDSSE dataset.
Expand All @@ -149,6 +159,7 @@ def load_open_event_data(
event_types:
coordinates:
event_factory:
exclude_penalty_shootouts: If True, excludes events from penalty shootouts (period 5).

Notes:
The dataset contains seven full matches of raw event and position data
Expand Down Expand Up @@ -180,6 +191,7 @@ def load_open_event_data(
event_types=event_types,
coordinates=coordinates,
event_factory=event_factory,
exclude_penalty_shootouts=exclude_penalty_shootouts,
)


Expand Down
6 changes: 6 additions & 0 deletions kloppy/_providers/statsbomb.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def load(
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
additional_metadata: dict = {},
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
"""
Load StatsBomb event data.
Expand All @@ -34,6 +35,7 @@ def load(
additional_metadata: A dict with additional data that will be added to
the metadata. See the [`Metadata`][kloppy.domain.Metadata] entity
for a list of possible keys.
exclude_penalty_shootouts: If True, excludes events from penalty shootouts (period 5).

Returns:
The parsed event data.
Expand All @@ -44,6 +46,7 @@ def load(
event_factory=event_factory
or get_config("event_factory")
or StatsBombEventFactory(),
exclude_penalty_shootouts=exclude_penalty_shootouts,
)
with open_as_file(event_data) as event_data_fp, open_as_file(
lineup_data
Expand All @@ -65,6 +68,7 @@ def load_open_data(
event_types: Optional[List[str]] = None,
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
"""
Load StatsBomb open data.
Expand All @@ -77,6 +81,7 @@ def load_open_data(
event_types: A list of event types to load.
coordinates: The coordinate system to use.
event_factory: A custom event factory.
exclude_penalty_shootouts: If True, excludes events from penalty shootouts (period 5).

Returns:
The parsed event data.
Expand Down Expand Up @@ -110,4 +115,5 @@ def load_open_data(
event_types=event_types,
coordinates=coordinates,
event_factory=event_factory,
exclude_penalty_shootouts=exclude_penalty_shootouts,
)
3 changes: 3 additions & 0 deletions kloppy/_providers/statsperform.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def load_event(
event_types: Optional[List[str]] = None,
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
"""Load Stats Perform event data.

Expand All @@ -69,6 +70,7 @@ def load_event(
event_types: A list of event types to load.
coordinates: The coordinate system to use.
event_factory: A custom event factory.
exclude_penalty_shootouts: If True, excludes events from penalty shootouts (period 5).

Returns:
The parsed event data.
Expand All @@ -77,6 +79,7 @@ def load_event(
event_types=event_types,
coordinate_system=coordinates,
event_factory=event_factory or get_config("event_factory"), # type: ignore
exclude_penalty_shootouts=exclude_penalty_shootouts,
)
with open_as_file(ma1_data) as ma1_data_fp, open_as_file(
ma3_data
Expand Down
6 changes: 6 additions & 0 deletions kloppy/_providers/wyscout.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def load(
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
data_version: Optional[str] = None,
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
"""
Load Wyscout event data.
Expand All @@ -28,6 +29,7 @@ def load(
coordinates: The coordinate system to use.
event_factory: A custom event factory.
data_version: The version of the Wyscout data. Supported versions are "V2" and "V3".
exclude_penalty_shootouts: If True, excludes events from penalty shootouts (period 5).

Returns:
The parsed event data.
Expand All @@ -43,6 +45,7 @@ def load(
event_types=event_types,
coordinate_system=coordinates,
event_factory=event_factory or get_config("event_factory"),
exclude_penalty_shootouts=exclude_penalty_shootouts,
)

with open_as_file(event_data) as event_data_fp:
Expand All @@ -56,6 +59,7 @@ def load_open_data(
event_types: Optional[List[str]] = None,
coordinates: Optional[str] = None,
event_factory: Optional[EventFactory] = None,
exclude_penalty_shootouts: bool = False,
) -> EventDataset:
"""
Load Wyscout open data.
Expand All @@ -71,6 +75,7 @@ def load_open_data(
event_types: A list of event types to load.
coordinates: The coordinate system to use.
event_factory: A custom event factory.
exclude_penalty_shootouts: If True, excludes events from penalty shootouts (period 5).

Returns:
The parsed event data.
Expand All @@ -87,6 +92,7 @@ def load_open_data(
event_types=event_types,
coordinates=coordinates,
event_factory=event_factory,
exclude_penalty_shootouts=exclude_penalty_shootouts,
)


Expand Down
7 changes: 6 additions & 1 deletion kloppy/infra/serializers/event/datafactory/deserializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,12 @@ def deserialize(self, inputs: DatafactoryInputs) -> EventDataset:
game_id=game_id,
)

return EventDataset(
dataset = EventDataset(
metadata=metadata,
records=events,
)

# Remove penalty shootout data if requested
dataset = self.remove_penalty_shootout_data(dataset)

return dataset
61 changes: 61 additions & 0 deletions kloppy/infra/serializers/event/deserializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def __init__(
event_types: Optional[List[Union[EventType, str]]] = None,
coordinate_system: Optional[Union[str, Provider]] = None,
event_factory: Optional[EventFactory] = None,
exclude_penalty_shootouts: bool = False,
):
if not event_types:
event_types = []
Expand All @@ -39,12 +40,72 @@ def __init__(
if not event_factory:
event_factory = EventFactory()
self.event_factory = event_factory
self.exclude_penalty_shootouts = exclude_penalty_shootouts

def should_include_event(self, event: Event) -> bool:
if (
self.exclude_penalty_shootouts
and event.period
and event.period.id == 5
):
return False
if not self.event_types:
return True
return event.event_type in self.event_types

def remove_penalty_shootout_data(
self, dataset: EventDataset
) -> EventDataset:
"""
Remove all penalty shootout data from the dataset including:
- Period 5 from metadata.periods
- Player positions associated with period 5
- Team formations associated with period 5
"""
if not self.exclude_penalty_shootouts:
return dataset

# Remove period 5 from metadata.periods
dataset.metadata.periods = [
period for period in dataset.metadata.periods if period.id != 5
]

# Update period references (prev/next) after removal
for i, period in enumerate(dataset.metadata.periods):
period.set_refs(
prev=dataset.metadata.periods[i - 1] if i > 0 else None,
next_=(
dataset.metadata.periods[i + 1]
if i + 1 < len(dataset.metadata.periods)
else None
),
)

# Remove player positions and team formations associated with period 5
for team in dataset.metadata.teams:
# Filter out formations for period 5
if team.formations.items:
times_to_remove = [
time
for time in team.formations.items.keys()
if time.period and time.period.id == 5
]
for time in times_to_remove:
del team.formations.items[time]

# Filter out player positions for period 5
for player in team.players:
if player.positions.items:
times_to_remove = [
time
for time in player.positions.items.keys()
if time.period and time.period.id == 5
]
for time in times_to_remove:
del player.positions.items[time]

return dataset

def get_transformer(
self,
pitch_length: Optional[float] = None,
Expand Down
Loading
Loading