Singular-Bean/sequence-sim
0
1from fastapi import FastAPI, Request, Response2from fastapi.middleware.cors import CORSMiddleware3import joblib4import numpy as np5import pandas as pd6from xgboost import XGBClassifier7 8app = FastAPI()9 10app.add_middleware(11 CORSMiddleware,12 allow_origins=["*"],13 allow_credentials=True,14 allow_methods=["*"],15 allow_headers=["*"],16)17 18choiceModel = joblib.load('models/choice_predictor.pkl')19passModel = joblib.load('models/pass_predictor.pkl')20moveModel = joblib.load('models/movement_predictor.pkl')21xModel = joblib.load('models/x_predictor.pkl')22yModel = joblib.load('models/y_predictor.pkl')23 24def convertCoordsTo(x=None, y=None):25 if x is not None:26 return 3+(x*1.05)27 elif y is not None:28 return 3+(y*0.68)29 30def convertCoordsFro(x=None, y=None):31 if x is not None:32 return (x-3)/1.0533 elif y is not None:34 return (y-3)/0.6835 36def predictNextPass(df, xModel, yModel, temperature=0.75):37 xDist = xModel.pred_dist(df[['xStart', 'yStart']])38 mu_x = xDist.loc[0]39 sigma_x = xDist.scale[0]40 simulated_x = np.random.normal(mu_x, sigma_x * temperature)41 while simulated_x < 0 or simulated_x > 100:42 simulated_x = np.random.normal(mu_x, sigma_x * temperature)43 df['xEnd'] = simulated_x44 yDist = yModel.pred_dist(df[['xStart', 'yStart', 'xEnd']])45 mu_y = yDist.loc[0]46 sigma_y = yDist.scale[0]47 simulated_y = np.random.normal(mu_y, sigma_y * temperature)48 while simulated_y < 0 or simulated_y > 100:49 simulated_y = np.random.normal(mu_y, sigma_y * temperature)50 return simulated_x, simulated_y51 52@app.get("/")53@app.get("/{cache_bust}")54async def hello(response: Response, cache_bust: str | None = None):55 response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"56 response.headers["Pragma"] = "no-cache"57 response.headers["Expires"] = "0"58 return {"success": True}59 60@app.post("/")61async def calc_path(request: Request):62 payload = await request.json()63 print(payload)64 65 inputX = convertCoordsFro(x=payload['end']['x'])66 inputY = convertCoordsFro(y=payload['end']['y'])67 68 def nextChoice(x, y):69 y_pred = choiceModel.predict_proba(pd.DataFrame({'1': {'x': float(x), 'y': float(y)}}).T)70 raw_probs = y_pred[0]71 72 probabilities = raw_probs / raw_probs.sum()73 74 options = ['Pass', 'Shot', 'Dribble']75 76 choice = np.random.choice(options, p=probabilities)77 return choice78 79 def passDestination(x, y):80 predX, predY = predictNextPass(pd.DataFrame({'1': {'xStart': float(x), 'yStart': float(y)}}).T, xModel, yModel)81 return predX, predY82 83 def dribbleDestination(x, y):84 y_pred = moveModel.predict(pd.DataFrame({'1': {'xStart': float(x), 'yStart': float(y)}}).T)85 return y_pred[0]86 87 sequence = []88 switch = True89 while switch:90 choice = nextChoice(inputX, inputY)91 if choice == 'Shot':92 sequence.append({"type": "shot", "x": 108, "y": 37})93 switch = False94 elif choice == 'Pass':95 inputX, inputY = passDestination(inputX, inputY)96 sequence.append({"type": "pass", "x": convertCoordsTo(x=inputX), "y": convertCoordsTo(y=inputY)})97 elif choice == 'Dribble':98 inputX, inputY = dribbleDestination(inputX, inputY)99 sequence.append({"type": "dribble", "x": convertCoordsTo(x=inputX), "y": convertCoordsTo(y=inputY)})100 return sequence101 