# Path: socceraction/spadl/schema.py
# class SPADLSchema(pa.SchemaModel):
#     """Definition of a SPADL dataframe."""
# 
#     game_id: Series[Any] = pa.Field()
#     original_event_id: Series[Any] = pa.Field(nullable=True)
#     action_id: Series[int] = pa.Field()
#     period_id: Series[int] = pa.Field(ge=1, le=5)
#     time_seconds: Series[float] = pa.Field(ge=0)
#     team_id: Series[Any] = pa.Field()
#     player_id: Series[Any] = pa.Field()
#     start_x: Series[float] = pa.Field(ge=0, le=spadlconfig.field_length)
#     start_y: Series[float] = pa.Field(ge=0, le=spadlconfig.field_width)
#     end_x: Series[float] = pa.Field(ge=0, le=spadlconfig.field_length)
#     end_y: Series[float] = pa.Field(ge=0, le=spadlconfig.field_width)
#     bodypart_id: Series[int] = pa.Field(isin=spadlconfig.bodyparts_df().bodypart_id)
#     bodypart_name: Optional[Series[str]] = pa.Field(isin=spadlconfig.bodyparts_df().bodypart_name)
#     type_id: Series[int] = pa.Field(isin=spadlconfig.actiontypes_df().type_id)
#     type_name: Optional[Series[str]] = pa.Field(isin=spadlconfig.actiontypes_df().type_name)
#     result_id: Series[int] = pa.Field(isin=spadlconfig.results_df().result_id)
#     result_name: Optional[Series[str]] = pa.Field(isin=spadlconfig.results_df().result_name)
# 
#     class Config:  # noqa: D106
#         strict = True
#         coerce = True


import json
import os
import warnings
import numpy as np
import numpy.typing as npt
import pandas as pd
import socceraction.spadl.config as spadlconfig
from typing import Callable, List, Optional, Tuple
from pandera.typing import DataFrame, Series
from sklearn.exceptions import NotFittedError
from socceraction.spadl.schema import SPADLSchema
    from scipy.interpolate import interp2d  # type: ignore
    x : pd.Series
        The x-coordinates of the actions.
    y : pd.Series
        The y-coordinates of the actions.
    l : int
        Amount of grid cells in the x-dimension of the grid.
    w : int
        Amount of grid cells in the y-dimension of the grid.

    Returns
    -------
    np.ndarray
        A matrix, denoting the amount of actions occurring in each cell. The
        top-left corner is the origin.
    """
    x = x[~np.isnan(x) & ~np.isnan(y)]
    y = y[~np.isnan(x) & ~np.isnan(y)]

    flat_indexes = _get_flat_indexes(x, y, l, w)
    vc = flat_indexes.value_counts(sort=False)
    vector = np.zeros(w * l)
    vector[vc.index] = vc
    return vector.reshape((w, l))


def _safe_divide(a: npt.ArrayLike, b: npt.ArrayLike) -> npt.NDArray[np.float64]:
    return np.divide(a, b, out=np.zeros_like(a), where=b != 0)


def scoring_prob(

# Path: socceraction/spadl/schema.py
# class SPADLSchema(pa.SchemaModel):
#     """Definition of a SPADL dataframe."""
# 
#     game_id: Series[Any] = pa.Field()
#     original_event_id: Series[Any] = pa.Field(nullable=True)
#     action_id: Series[int] = pa.Field()
#     period_id: Series[int] = pa.Field(ge=1, le=5)
#     time_seconds: Series[float] = pa.Field(ge=0)
#     team_id: Series[Any] = pa.Field()
#     player_id: Series[Any] = pa.Field()
#     start_x: Series[float] = pa.Field(ge=0, le=spadlconfig.field_length)
#     start_y: Series[float] = pa.Field(ge=0, le=spadlconfig.field_width)
#     end_x: Series[float] = pa.Field(ge=0, le=spadlconfig.field_length)
#     end_y: Series[float] = pa.Field(ge=0, le=spadlconfig.field_width)
#     bodypart_id: Series[int] = pa.Field(isin=spadlconfig.bodyparts_df().bodypart_id)
#     bodypart_name: Optional[Series[str]] = pa.Field(isin=spadlconfig.bodyparts_df().bodypart_name)
#     type_id: Series[int] = pa.Field(isin=spadlconfig.actiontypes_df().type_id)
#     type_name: Optional[Series[str]] = pa.Field(isin=spadlconfig.actiontypes_df().type_name)
#     result_id: Series[int] = pa.Field(isin=spadlconfig.results_df().result_id)
#     result_name: Optional[Series[str]] = pa.Field(isin=spadlconfig.results_df().result_name)
# 
#     class Config:  # noqa: D106
#         strict = True
#         coerce = True


# Path: socceraction/xthreat.py
import json
import os
import warnings
import numpy as np
import numpy.typing as npt
import pandas as pd
import socceraction.spadl.config as spadlconfig
from typing import Callable, List, Optional, Tuple
from pandera.typing import DataFrame, Series
from sklearn.exceptions import NotFittedError
from socceraction.spadl.schema import SPADLSchema
    from scipy.interpolate import interp2d  # type: ignore

    x : pd.Series
        The x-coordinates of the actions.
    y : pd.Series
        The y-coordinates of the actions.
    l : int
        Amount of grid cells in the x-dimension of the grid.
    w : int
        Amount of grid cells in the y-dimension of the grid.

    Returns
    -------
    np.ndarray
        A matrix, denoting the amount of actions occurring in each cell. The
        top-left corner is the origin.
    """
    x = x[~np.isnan(x) & ~np.isnan(y)]
    y = y[~np.isnan(x) & ~np.isnan(y)]

    flat_indexes = _get_flat_indexes(x, y, l, w)
    vc = flat_indexes.value_counts(sort=False)
    vector = np.zeros(w * l)
    vector[vc.index] = vc
    return vector.reshape((w, l))


def _safe_divide(a: npt.ArrayLike, b: npt.ArrayLike) -> npt.NDArray[np.float64]:
    return np.divide(a, b, out=np.zeros_like(a), where=b != 0)


def scoring_prob(

    actions: DataFrame[SPADLSchema], l: int = N, w: int = M