Example #1
0
    def test_read(self):
        base_dir = os.path.dirname(__file__)
        with open(
            f"{base_dir}/files/epts_metrica_metadata.xml", "rb"
        ) as metadata_fp:
            metadata = load_metadata(metadata_fp)

        with open(
            f"{base_dir}/files/epts_metrica_tracking.txt", "rb"
        ) as raw_data:
            iterator = read_raw_data(raw_data, metadata)

            with performance_logging("load"):
                assert list(iterator)
Example #2
0
    def test_skip_sensors(self):
        base_dir = os.path.dirname(__file__)

        with open(
            f"{base_dir}/files/epts_metrica_metadata.xml", "rb"
        ) as metadata_fp, open(
            f"{base_dir}/files/epts_metrica_tracking.txt", "rb"
        ) as raw_data:
            metadata = load_metadata(metadata_fp)
            records = read_raw_data(raw_data, metadata, sensor_ids=["speed"])
            data_frame = DataFrame.from_records(records)

        assert "player_Track_1_s" in data_frame.columns
        assert "player_Track_1_x" not in data_frame.columns
Example #3
0
    def test_regex(self):
        base_dir = os.path.dirname(__file__)
        with open(
            f"{base_dir}/files/epts_metrica_metadata.xml", "rb"
        ) as metadata_fp:
            metadata = load_metadata(metadata_fp)

        regex_str = build_regex(
            metadata.data_format_specifications[0],
            metadata.player_channels,
            metadata.sensors,
        )

        regex = re.compile(regex_str)

        result = regex.search(
            "450:0.30602,0.97029,5,1.1127902269363403;0.48496,0.73308,1,5.2345757484436035;0.38851,0.97786,2,3.32438325881958;0.48414,0.92730,0,5.878201961517334;0.25661,0.60984,8,4.325275421142578;0.24170,0.49115,7,1.9475973844528198;0.38878,0.47540,4,1.8947187662124634;0.31854,0.89154,3,2.741175413131714;NaN,NaN,-1,NaN;0.25658,0.73095,9,3.418901205062866;NaN,NaN,10,NaN;0.32513,0.89532,19,0.6292267441749573;0.30286,0.98231,17,1.287971019744873;0.39954,0.93079,12,3.8761117458343506;0.23961,0.63742,20,1.6785365343093872;0.38319,0.81908,14,3.611333131790161;0.49984,0.91227,13,5.139825820922852;0.46733,0.49708,16,3.1186790466308594;0.26311,0.48218,18,2.309934139251709;0.53767,0.81373,11,6.402815818786621;0.39631,0.77277,15,3.338606357574463;NaN,NaN,21,NaN:0.52867,0.70690,NaN"
        )

        assert result is not None
Example #4
0
    def deserialize(self, inputs: MetricaJsonEventDataInputs) -> EventDataset:
        with performance_logging("load data", logger=logger):
            raw_events = json.load(inputs.event_data)
            metadata = load_metadata(inputs.meta_data,
                                     provider=Provider.METRICA)

            transformer = self.get_transformer(
                length=metadata.pitch_dimensions.length,
                width=metadata.pitch_dimensions.width,
            )

        with performance_logging("parse data", logger=logger):
            events = []
            for i, raw_event in enumerate(raw_events["data"]):

                if raw_event["team"]["id"] == metadata.teams[0].team_id:
                    team = metadata.teams[0]
                elif raw_event["team"]["id"] == metadata.teams[1].team_id:
                    team = metadata.teams[1]
                else:
                    raise DeserializationError(
                        f"Unknown team_id {raw_event['team']['id']}")

                player = team.get_player_by_id(raw_event["from"]["id"])
                event_type = raw_event["type"]["id"]
                subtypes = _parse_subtypes(raw_event)
                period = [
                    period for period in metadata.periods
                    if period.id == raw_event["period"]
                ][0]
                previous_event = raw_events["data"][i - 1]

                generic_event_kwargs = dict(
                    # from DataRecord
                    period=period,
                    timestamp=raw_event["start"]["time"],
                    ball_owning_team=_parse_ball_owning_team(event_type, team),
                    ball_state=BallState.ALIVE,
                    # from Event
                    event_id=None,
                    team=team,
                    player=player,
                    coordinates=(_parse_coordinates(raw_event["start"])),
                    raw_event=raw_event,
                )

                iteration_events = []

                if event_type in MS_PASS_TYPES:
                    pass_event_kwargs = _parse_pass(
                        event=raw_event,
                        previous_event=previous_event,
                        subtypes=subtypes,
                        team=team,
                    )

                    event = PassEvent.create(
                        **pass_event_kwargs,
                        **generic_event_kwargs,
                    )

                elif event_type == MS_EVENT_TYPE_SHOT:
                    shot_event_kwargs = _parse_shot(
                        event=raw_event,
                        previous_event=previous_event,
                        subtypes=subtypes,
                    )
                    event = ShotEvent.create(
                        **shot_event_kwargs,
                        **generic_event_kwargs,
                    )

                elif subtypes and MS_EVENT_TYPE_DRIBBLE in subtypes:
                    take_on_event_kwargs = _parse_take_on(subtypes=subtypes)
                    event = TakeOnEvent.create(
                        qualifiers=None,
                        **take_on_event_kwargs,
                        **generic_event_kwargs,
                    )

                elif event_type == MS_EVENT_TYPE_CARRY:
                    carry_event_kwargs = _parse_carry(event=raw_event, )
                    event = CarryEvent.create(
                        qualifiers=None,
                        **carry_event_kwargs,
                        **generic_event_kwargs,
                    )

                elif event_type == MS_EVENT_TYPE_RECOVERY:
                    event = RecoveryEvent.create(
                        result=None,
                        qualifiers=None,
                        **generic_event_kwargs,
                    )

                elif event_type == MS_EVENT_TYPE_FOUL_COMMITTED:
                    event = FoulCommittedEvent.create(
                        result=None,
                        qualifiers=None,
                        **generic_event_kwargs,
                    )

                else:
                    event = GenericEvent.create(
                        result=None,
                        qualifiers=None,
                        event_name=raw_event["type"]["name"],
                        **generic_event_kwargs,
                    )

                if self.should_include_event(event):
                    events.append(transformer.transform_event(event))

                # Checks if the event ended out of the field and adds a synthetic out event
                if event.result in OUT_EVENT_RESULTS:
                    generic_event_kwargs["ball_state"] = BallState.DEAD
                    if raw_event["end"]["x"]:
                        generic_event_kwargs[
                            "coordinates"] = _parse_coordinates(
                                raw_event["end"])
                        generic_event_kwargs["timestamp"] = raw_event["end"][
                            "time"]

                        event = BallOutEvent.create(
                            result=None,
                            qualifiers=None,
                            **generic_event_kwargs,
                        )

                        if self.should_include_event(event):
                            events.append(transformer.transform_event(event))

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