Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix conflicts and make project stable #82

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
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
33 changes: 12 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,18 @@ $ pip install socceranalyzer
This package is capable of delivering built-in analysis that were already
created or to be a platform that enables you to create your own analysis.

### Parameters
Before SoccerAnalyzer execute it's analysis, it consumes a configuration [file](configuration.yml). **You should change this file values in order to SoccerAnalyzer work as you expect.**

| Parameters | Type | Default value |
| ------------- | ------------- | ---------------- |
| -v, --version | `string` | `None` |
| -f, --file | `string` | configuration.yml |

The [configuration.yml](configuration.yml) is responsible for setting up your SoccerAnalyzer execution. All analysis should be mapped into a entry here. You should specify your .csv log file path, category, and which analysis do you want to run.

### Using as analyzer
##### How it works?
##### How does it work?
Each analysis is a class, they are instantiated and interfaced by a [Facade](https://refactoring.guru/design-patterns/facade)
which is the **common.chore.match_analyzer** module. It is responsible for
creating each analysis object.
Expand All @@ -66,36 +76,17 @@ The **Match** receives a **pandas.DataFrame** and a **Category** object as param

These inputs are **mandatory**, otherwise there will be no data to be analyzed.

##### 2D Simulation code example
##### Code example

```python
import pandas as pd

from socceranalyzer import MatchAnalyzer, Match, SIM2D

SIM2D_LOGFILE_PATH = "location/to/log/file2d.csv"
dataframe = pd.read_csv(SIM2D_LOGFILE_PATH)

match_object = Match(dataframe, SIM2D)
match_analyzer = MatchAnalyzer(match_object)
match_analyzer.collect_results()
```
##### SSL
```python
import pandas as pd

from socceranalyzer import MatchAnalyzer, Match, SSL

SSL_LOGFILE_PATH = "location/to/log/filessl.csv"
dataframe = pd.read_csv(SSL_LOGFILE_PATH)

match_object = Match(dataframe, SSL)
match_analyzer = MatchAnalyzer(match_object)
match_analyzer.collect_results()
```

#### VSS
> Not available yet

---
> 2021, RobôCIn
Expand Down
25 changes: 0 additions & 25 deletions config.json

This file was deleted.

42 changes: 22 additions & 20 deletions configuration.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
category: ssl
logs_folder: path/to/unified/logs
file_path: /home/emilly/github/SoccerAnalyzer/socceranalyzer/objPositions.csv
category: string
logs_folder: string
file_path: string
analysis:
tester_2d: false
ball_possession: false
foul_charge: false
playmodes: false
ball_history: false
penalty: false
passing_accuracy: false
corners_occurrencies: false
tester_free_kick: false
intercept_counter: false
stamina: false
time_after_events: false
heatmap: true
shooting: false
speed: false
find_goals: false
goalkeeper: false
tester_2d: boolean
ball_possession: boolean
foul_charge: boolean
playmodes: boolean
ball_history: boolean
penalty: boolean
passing_accuracy: boolean
corners_occurrencies: boolean
tester_free_kick: boolean
intercept_counter: boolean
stamina: boolean
time_after_events: boolean
heatmap: boolean
shooting: boolean
speed: boolean
find_goals: boolean
goalkeeper: boolean
kick_in: boolean
kick_in_occurrences: boolean
8 changes: 2 additions & 6 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import pandas as pd
import argparse

from socceranalyzer import Match, MatchAnalyzer, SIM2D, JsonReader, YamlReader, RunConfiguration, Logger
from socceranalyzer import Match, MatchAnalyzer,YamlReader, RunConfiguration

def setup():
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument("run", help="run analysis")
arg_parser.add_argument("-v", "--version", help="show socceranalyzer version")
arg_parser.add_argument("-f", "--file", help="configuration file, either json or yml")
arg_parser.add_argument("-f", "--file", help="configuration file, either json or yml", default="configuration.yml")
args = arg_parser.parse_args()

info = YamlReader.read(args.file)
Expand All @@ -23,6 +22,3 @@ def setup():
dataframe = pd.read_csv(config.file_path)
match = Match(dataframe, config.category)
match_analyzer = MatchAnalyzer(match,run_config=config)

adapter = JupyterAdapter(match_analyzer)
adapter.goalkeeper()
6 changes: 3 additions & 3 deletions socceranalyzer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# Abstract
from socceranalyzer.common.analysis.abstract_analysis import AbstractAnalysis
from socceranalyzer.common.entity.abstract_player import AbstractPlayer
from socceranalyzer.common.chore.abstract_factory import AbstractFactory
from socceranalyzer.common.core.abstract_factory import AbstractFactory

# Entities
from socceranalyzer.common.basic.team import Team
Expand All @@ -26,8 +26,8 @@
from socceranalyzer.common.enums.ssl import SSL

# Chore
from socceranalyzer.common.chore.match_analyzer import MatchAnalyzer
from socceranalyzer.common.chore.mediator import Mediator
from socceranalyzer.common.core.match_analyzer import MatchAnalyzer
from socceranalyzer.common.core.mediator import Mediator

# Collections
from socceranalyzer.common.collections.collections import PlayersCollection
Expand Down
2 changes: 1 addition & 1 deletion socceranalyzer/common/analysis/ball_possession.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from socceranalyzer.common.enums.sim2d import SIM2D
from socceranalyzer.common.enums.ssl import SSL
from socceranalyzer.utils.logger import Logger
from socceranalyzer.common.chore.mediator import Mediator
from socceranalyzer.common.core.mediator import Mediator
from socceranalyzer.common.geometric.point import Point
from socceranalyzer.common.operations.measures import distance_sqrd

Expand Down
2 changes: 1 addition & 1 deletion socceranalyzer/common/analysis/goalkeeper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from socceranalyzer.common.enums.vss import VSS
from socceranalyzer.common.analysis.find_goals import FindGoals
from socceranalyzer.common.geometric.point import Point
from socceranalyzer.common.chore.mediator import Mediator
from socceranalyzer.common.core.mediator import Mediator
from socceranalyzer.common.operations.measures import distance
from socceranalyzer.utils.logger import Logger

Expand Down
48 changes: 34 additions & 14 deletions socceranalyzer/common/analysis/heatmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,26 @@
import seaborn as sns
import os

from socceranalyzer.common.basic.match import Match
from socceranalyzer.common.analysis.abstract_analysis import AbstractAnalysis
from socceranalyzer.common.chore.mediator import Mediator
from socceranalyzer.common.core.mediator import Mediator
from socceranalyzer.common.enums.sim2d import SIM2D
from socceranalyzer.common.enums.ssl import SSL
from socceranalyzer.common.enums.vss import VSS
from socceranalyzer.common.geometric.point import Point
from socceranalyzer.common.enums.category import Category
from socceranalyzer.utils.logger import Logger
from socceranalyzer.common.basic.field import Field

class HeatmapDimensions:
""" l = left
r = right
d = down
u = up
"""
Used to hold values to matplotlib.pyplot axes dimensions.
Values assigned here are used in Heatmap.plot() method.

Atrtibute prepends
--------
Left (l)
Right (r)
Upper (u)
Down (d)
"""
def __init__(self):
self.l_side_end = -4500
Expand All @@ -33,13 +38,25 @@ def __init__(self):
self.d_side_first_mark = -1000
self.u_side_first_mark = 1000
self.u_side_second_mark = 2000
self.u_side_side_end = 3000
self.u_side_side_end = 3000

class Heatmap(AbstractAnalysis):
def __init__(self, dataframe: pandas.DataFrame, category: SSL | SIM2D | VSS, debug, plot_players = True) -> None:
def __init__(self,
dataframe: pandas.DataFrame,
category: SSL | SIM2D | VSS,
debug,
plot_players = True,
category_v2: Category = Category.SSL
) -> None:

self.__dataframe = dataframe
self.__category = category

#todo(fnap):
# refactor this usage with current category in all analysis. Needed due to name capture in match pattern matching.
# https://stackoverflow.com/questions/67525257/capture-makes-remaining-patterns-unreachable
self.__category_v2 = category_v2

self.left_players_x = []
self.left_players_y = []

Expand All @@ -59,6 +76,7 @@ def __init__(self, dataframe: pandas.DataFrame, category: SSL | SIM2D | VSS, deb
raise
else:
Logger.success("Heatmap has results.")

@property
def dataframe(self):
return self.__dataframe
Expand Down Expand Up @@ -95,9 +113,8 @@ def _analyze(self):

def plot(self):
fig, ax = plt.subplots(figsize=(13.5, 8))
image = "../../images/ssl-pitch.png"
field = Field(width = 3000, length = 4500)
self._background(field, image, ax)
self._background(field, ax)

if self.__plot_players:
sns.kdeplot(x=self.left_players_x, y=self.left_players_y, fill=True, thresh=0.05, n_levels = 7, alpha=0.5, cmap='Greens')
Expand All @@ -110,21 +127,24 @@ def plot(self):

plt.show()

def _background(self, field, image_path, ax):
def _background(self, field, ax):
dimensions = HeatmapDimensions()
image_path = f'{os.getcwd()}/socceranalyzer/images/{self.__category.NAME}_field.png'
module_path = os.path.dirname(os.path.abspath(__file__))
absolute_image_path = os.path.join(module_path, image_path)
soccer_pitch = plt.imread(absolute_image_path)

ax.imshow(soccer_pitch, extent=[-field.length, field.length, -field.width, field.width])
ax.set_xlim(-field.length, field.length)
ax.set_ylim(-field.width, field.width)
dimensions = HeatmapDimensions()
ax.set_xticks([dimensions.l_side_end, dimensions.l_side_second_mark, dimensions.l_side_first_mark , dimensions.center, dimensions.r_side_first_mark, dimensions.r_side_second_mark, dimensions.r_side_end])
ax.set_yticks([dimensions.d_side_end, dimensions.d_side_second_mark,dimensions.d_side_first_mark, dimensions.center, dimensions.u_side_first_mark, dimensions.u_side_second_mark , dimensions.u_side_side_end])

def describe(self):
raise NotImplementedError

def results(self, config: dict[str, list[int]], ball: bool):
pass
raise NotImplementedError

def serialize(self):
raise NotImplementedError
Expand Down
2 changes: 1 addition & 1 deletion socceranalyzer/common/analysis/stamina.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pandas
from socceranalyzer.common.analysis.abstract_analysis import AbstractAnalysis
from socceranalyzer.common.enums.sim2d import SIM2D
from socceranalyzer.common.chore.mediator import Mediator
from socceranalyzer.common.core.mediator import Mediator
from socceranalyzer.common.enums.ssl import SSL
from socceranalyzer.common.enums.vss import VSS
from socceranalyzer.utils.logger import Logger
Expand Down
2 changes: 1 addition & 1 deletion socceranalyzer/common/basic/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from socceranalyzer.common.basic.field import Field
from socceranalyzer.common.basic.ball import Ball
from socceranalyzer.common.basic.team import Team
from socceranalyzer.common.chore.builder import Builder
from socceranalyzer.common.core.builder import Builder
from socceranalyzer.agent2D.agent import Agent2D
from socceranalyzer.utils.logger import Logger

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from time import time
from socceranalyzer.common.analysis.speed import Speed

from socceranalyzer.common.chore.abstract_factory import AbstractFactory
from socceranalyzer.common.chore.builder import Builder
from socceranalyzer.common.core.abstract_factory import AbstractFactory
from socceranalyzer.common.core.builder import Builder

from socceranalyzer.common.basic.match import Match
from socceranalyzer.common.collections.collections import EvaluatorCollection
Expand Down
8 changes: 8 additions & 0 deletions socceranalyzer/common/enums/category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from enum import Enum

class Category(Enum):
UNKNOWN = 0
SSL = 1
SIM2D = 2
VSS = 3
DRONE = 4
1 change: 1 addition & 0 deletions socceranalyzer/common/enums/sim2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class SIM2D(Enum):

All parameters are strings
"""
NAME = "sim2d"
GAME_TIME = "show_time"
PLAYMODE = "playmode"
RUNNING_GAME = "play_on"
Expand Down
2 changes: 1 addition & 1 deletion socceranalyzer/common/enums/ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class SSL(Enum):

All parameters are strings
"""

NAME = "ssl"
GAME_TIME = "showtime"
PLAYMODE = "game_state_name"
RUNNING_GAME = "GameRunning"
Expand Down
2 changes: 1 addition & 1 deletion socceranalyzer/common/evaluators/ball_holder.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from socceranalyzer.common.geometric.point import Point

from socceranalyzer.common.geometric.circle import Circle
from socceranalyzer.common.chore.mediator import Mediator
from socceranalyzer.common.core.mediator import Mediator
from socceranalyzer.common.operations.measures import distance

class BallHolderEvaluator:
Expand Down
1 change: 1 addition & 0 deletions socceranalyzer/common/evaluators/kick.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# deprecated
def kick(cycle, team, df, player_who_kicked=False):
for player_num in range(1,12):
if cycle != 0:
Expand Down
2 changes: 1 addition & 1 deletion socceranalyzer/common/evaluators/passing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Any
from pandas import DataFrame
from socceranalyzer.common.chore.mediator import Mediator
from socceranalyzer.common.core.mediator import Mediator
from socceranalyzer.common.enums.sim2d import SIM2D
from socceranalyzer.common.enums.ssl import SSL
from socceranalyzer.common.enums.vss import VSS
Expand Down
Binary file added socceranalyzer/images/ssl_field.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion socceranalyzer/jupyter/jupyter_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import socceranalyzer
from socceranalyzer.common.analysis.speed import Speed
from socceranalyzer.common.chore.match_analyzer import MatchAnalyzer
from socceranalyzer.common.core.match_analyzer import MatchAnalyzer
from socceranalyzer.common.enums.sim2d import Landmarks


Expand Down
Loading