osama-n097/match-performance-api
0
1"""2config.py — Project Configuration3Match Performance Analysis — Sports Performance Management Platform4"""5 6import os7from pathlib import Path8 9# ── Paths ──────────────────────────────────────────────────────────────────────10BASE_DIR = Path(__file__).parent11DATA_DIR = BASE_DIR / "data"12MODELS_DIR = BASE_DIR / "models"13 14# ── StatsBomb ──────────────────────────────────────────────────────────────────15TARGET_TEAM = "Barcelona"16 17# Multi-season support: (competition_id, season_id, label)18# La Liga = competition 11, Champions League = 16, Copa del Rey = 8719SEASONS_LIST = [20 (11, 22, "2010/2011"), (11, 23, "2011/2012"),21 (11, 24, "2012/2013"), (11, 25, "2013/2014"),22 (11, 26, "2014/2015"), (11, 27, "2015/2016"),23 (11, 2, "2016/2017"), (11, 4, "2017/2018"),24 (11, 42, "2018/2019"), (11, 90, "2019/2020"),25 (11, 1, "2020/2021"),26]27 28# Default season for backward compatibility (originally 2015/2016)29COMPETITION_ID = 1130SEASON_ID = 2731 32# Season label to season_id lookup33SEASON_LABEL_MAP = {label: sid for _, sid, label in SEASONS_LIST}34SEASON_ID_MAP = {sid: label for _, sid, label in SEASONS_LIST}35 36# ── VAEP ───────────────────────────────────────────────────────────────────────37VAEP_WINDOW = 10 # عدد الـ actions للتنبؤ38VAEP_N_CONTEXT = 3 # عدد الـ actions السابقة39 40# ── Scoring ────────────────────────────────────────────────────────────────────41# Legacy dimension weights (for backward compatibility)42POSITION_WEIGHTS = {43 "Attacker": {44 "passing_score": 0.15,45 "shooting_score": 0.30,46 "positioning_score": 0.20,47 "pressing_score": 0.10,48 "movement_score": 0.10,49 "physical_score": 0.08,50 "behavioral_score": 0.07,51 },52 "Midfielder": {53 "passing_score": 0.28,54 "shooting_score": 0.12,55 "positioning_score": 0.18,56 "pressing_score": 0.18,57 "movement_score": 0.12,58 "physical_score": 0.07,59 "behavioral_score": 0.05,60 },61 "Defender": {62 "passing_score": 0.18,63 "shooting_score": 0.05,64 "positioning_score": 0.25,65 "pressing_score": 0.22,66 "movement_score": 0.10,67 "physical_score": 0.12,68 "behavioral_score": 0.08,69 },70 "GK": {71 "passing_score": 0.20,72 "shooting_score": 0.02,73 "positioning_score": 0.30,74 "pressing_score": 0.15,75 "movement_score": 0.08,76 "physical_score": 0.15,77 "behavioral_score": 0.10,78 },79}80 81# ── V2 Scoring: 4-Pillar Contribution Model ──82# Position weights for the four contribution sub-scores83CONTRIBUTION_WEIGHTS = {84 "Attacker": {"offensive": 0.50, "defensive": 0.05, "possession": 0.20, "event_value": 0.25},85 "Midfielder": {"offensive": 0.25, "defensive": 0.15, "possession": 0.35, "event_value": 0.25},86 "Defender": {"offensive": 0.10, "defensive": 0.40, "possession": 0.25, "event_value": 0.25},87 "GK": {"offensive": 0.02, "defensive": 0.50, "possession": 0.23, "event_value": 0.25},88}89 90# Feature-level weights within each contribution pillar (per position)91# Each key maps to (feature_name, weight) pairs92OFFENSIVE_FEATURES = {93 "Attacker": {"total_shots": 0.15, "predicted_xg": 0.25, "shot_accuracy": 0.10, "goals": 0.20, "xg_overperformance": 0.10, "progressive_passes": 0.05, "progressive_carries": 0.05, "successful_dribbles": 0.05, "total_carries": 0.05},94 "Midfielder": {"total_shots": 0.10, "predicted_xg": 0.10, "shot_accuracy": 0.05, "goals": 0.05, "xg_overperformance": 0.05, "progressive_passes": 0.25, "progressive_carries": 0.15, "successful_dribbles": 0.10, "total_carries": 0.10, "passes_under_pressure": 0.05},95 "Defender": {"total_shots": 0.05, "predicted_xg": 0.05, "goals": 0.05, "progressive_passes": 0.30, "progressive_carries": 0.30, "successful_dribbles": 0.10, "total_carries": 0.15},96 "GK": {"total_shots": 0.00, "goals": 0.00, "progressive_passes": 0.50, "total_carries": 0.50},97}98 99DEFENSIVE_FEATURES = {100 "Attacker": {"total_pressures": 0.40, "pressure_regains": 0.30, "pressing_efficiency": 0.20, "fouls_won": 0.10},101 "Midfielder": {"total_pressures": 0.30, "pressure_regains": 0.25, "pressing_efficiency": 0.15, "fouls_committed": -0.10, "fouls_won": 0.10, "yellow_cards": -0.05, "red_cards": -0.10},102 "Defender": {"total_pressures": 0.25, "pressure_regains": 0.20, "pressing_efficiency": 0.10, "fouls_committed": -0.10, "fouls_won": 0.15, "yellow_cards": -0.10, "red_cards": -0.15, "miscontrols": -0.05},103 "GK": {"total_pressures": 0.10, "pressure_regains": 0.10, "fouls_committed": -0.10, "yellow_cards": -0.05, "red_cards": -0.20, "miscontrols": -0.10},104}105 106POSSESSION_FEATURES = {107 "Attacker": {"pass_accuracy": 0.25, "total_passes": 0.10, "ball_retention_rate": 0.20, "ball_receipts": 0.15, "miscontrols": -0.10, "progressive_passes": 0.10, "passes_under_pressure": 0.10},108 "Midfielder": {"pass_accuracy": 0.20, "total_passes": 0.20, "ball_retention_rate": 0.15, "ball_receipts": 0.15, "miscontrols": -0.10, "progressive_passes": 0.10, "passes_under_pressure": 0.10},109 "Defender": {"pass_accuracy": 0.25, "total_passes": 0.15, "ball_retention_rate": 0.20, "ball_receipts": 0.10, "miscontrols": -0.10, "progressive_passes": 0.10, "passes_under_pressure": 0.10},110 "GK": {"pass_accuracy": 0.30, "total_passes": 0.15, "ball_retention_rate": 0.25, "ball_receipts": 0.10, "miscontrols": -0.10, "progressive_passes": 0.10},111}112 113# Legacy 7-dimension score columns114SCORE_COLS = [115 "passing_score","shooting_score","positioning_score","pressing_score",116 "movement_score","physical_score","behavioral_score"117]118 119# Rating scale labels120RATING_LABELS = {121 (9.0, 10.0): "Exceptional",122 (8.0, 9.0): "Excellent",123 (7.0, 8.0): "Very Good",124 (6.0, 7.0): "Good",125 (5.0, 6.0): "Average",126 (0.0, 5.0): "Below Average",127}128 129POSITION_MAP = {130 "Goalkeeper": "GK",131 "Right Back": "Defender",132 "Left Back": "Defender",133 "Center Back": "Defender",134 "Right Center Back": "Defender",135 "Left Center Back": "Defender",136 "Right Wing Back": "Defender",137 "Left Wing Back": "Defender",138 "Defensive Midfield": "Midfielder",139 "Center Midfield": "Midfielder",140 "Right Center Midfield": "Midfielder",141 "Left Center Midfield": "Midfielder",142 "Attacking Midfield": "Midfielder",143 "Right Midfield": "Midfielder",144 "Left Midfield": "Midfielder",145 "Right Wing": "Attacker",146 "Left Wing": "Attacker",147 "Right Center Forward": "Attacker",148 "Left Center Forward": "Attacker",149 "Center Forward": "Attacker",150 "Secondary Striker": "Attacker",151}152 153# Granular position mapping (8 roles) — Phase 4.5154GRANULAR_POSITION_MAP = {155 "Goalkeeper": "Goalkeeper",156 "Right Back": "Full Back",157 "Left Back": "Full Back",158 "Center Back": "Center Back",159 "Right Center Back": "Center Back",160 "Left Center Back": "Center Back",161 "Right Wing Back": "Full Back",162 "Left Wing Back": "Full Back",163 "Defensive Midfield": "Defensive Midfielder",164 "Center Midfield": "Central Midfielder",165 "Right Center Midfield": "Central Midfielder",166 "Left Center Midfield": "Central Midfielder",167 "Attacking Midfield": "Attacking Midfielder",168 "Right Midfield": "Winger",169 "Left Midfield": "Winger",170 "Right Wing": "Winger",171 "Left Wing": "Winger",172 "Right Center Forward": "Striker",173 "Left Center Forward": "Striker",174 "Center Forward": "Striker",175 "Secondary Striker": "Attacking Midfielder",176}177 178GRANULAR_POSITION_LABELS = {179 "Goalkeeper": "GK", "Center Back": "CB", "Full Back": "FB",180 "Defensive Midfielder": "DMF", "Central Midfielder": "CMF",181 "Attacking Midfielder": "AMF", "Winger": "WG", "Striker": "ST",182}183 184ACTION_TYPE_MAP = {185 "Pass": "pass",186 "Shot": "shot",187 "Dribble": "dribble",188 "Carry": "carry",189 "Pressure": "tackle",190 "Foul Committed": "foul",191 "Clearance": "clearance",192 "Interception": "interception",193 "Block": "shot_block",194 "Goal Keeper": "keeper_save",195 "Ball Receipt*": "receival",196 "Miscontrol": "bad_touch",197}198 199CLUSTER_NAMES = {200 0: "Creative Playmaker",201 1: "Box-to-Box Midfielder",202 2: "Target Forward",203 3: "Ball-Playing Defender",204 4: "Pressing Machine",205}206 207# ── API ────────────────────────────────────────────────────────────────────────208API_HOST = "0.0.0.0"209API_PORT = 8000210API_VERSION = "v1"211API_PREFIX = f"/api/{API_VERSION}"212 213# ── Colors (for visualizations) ───────────────────────────────────────────────214VIZ_COLORS = {215 "primary": "#1F4E79",216 "secondary": "#2E75B6",217 "accent": "#E67E22",218 "success": "#27AE60",219 "danger": "#C0392B",220 "pitch_dark": "#22312b",221 "pitch_light": "grass",222}223 