Spaces:
Runtime error
Runtime error
| # from git import Repo | |
| # import os | |
| # GITHUB_PAT = os.environ['GITHUB'] | |
| # if not os.path.exists('repo_directory'): | |
| # # os.mkdir('repo_directory') | |
| # Repo.clone_from(f'https://tracinginsights:{GITHUB_PAT}@github.com/TracingInsights/fastf1api.git', 'repo_directory' ) | |
| # from repo_directory.main import * | |
| import concurrent.futures | |
| import datetime | |
| import functools | |
| import math | |
| import os | |
| from io import BytesIO | |
| import fastf1 | |
| import numpy as np | |
| import pandas as pd | |
| import requests | |
| import streamlit as st | |
| from fastapi import Depends, FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import FileResponse, HTMLResponse | |
| from fastf1.ergast import Ergast | |
| from pydantic import BaseModel, Field | |
| from sqlalchemy.orm import Session | |
| # from . import accelerations, database, models, utils | |
| import accelerations | |
| import database | |
| import models | |
| import utils | |
| FASTF1_CACHE_DIR = os.environ["FASTF1_CACHE_DIR"] | |
| fastf1.Cache.enable_cache(FASTF1_CACHE_DIR) | |
| app = FastAPI() | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| database.Base.metadata.create_all(bind=database.engine) | |
| def get_db(): | |
| try: | |
| db = database.SessionLocal() | |
| yield db | |
| finally: | |
| db.close() | |
| class RacePace(BaseModel): | |
| year: int | |
| event: str | |
| session: str | |
| Driver: str | |
| LapTime: float | |
| Diff: float | |
| Team: str | |
| fill: str | |
| # @functools.cache | |
| async def average_race_pace( | |
| year: int, event: str | int, session: str, db: Session = Depends(get_db) | |
| ) -> any: | |
| race_pace_data = ( | |
| db.query(models.RacePace) | |
| .filter_by(year=year, event=event, session=session) | |
| .all() | |
| ) | |
| if race_pace_data: | |
| print("Fetching from Database") | |
| if not race_pace_data: | |
| print("Writing to Database") | |
| f1session = fastf1.get_session( | |
| year, | |
| event, | |
| session, | |
| # backend="fastf1", | |
| # force_ergast=False, | |
| ) | |
| f1session.load(telemetry=False, weather=False, messages=False) | |
| laps = f1session.laps | |
| laps = laps.loc[laps.LapNumber > 1] | |
| laps = laps.pick_track_status( | |
| "1", | |
| ) | |
| laps["LapTime"] = laps.Sector1Time + laps.Sector2Time + laps.Sector3Time | |
| # convert LapTime to seconds | |
| laps["LapTime"] = laps["LapTime"].apply(lambda x: x.total_seconds()) | |
| laps = laps.loc[laps.LapTime < laps.LapTime.min() * 1.07] | |
| df = ( | |
| laps[["LapTime", "Driver"]].groupby("Driver").mean().reset_index(drop=False) | |
| ) | |
| df = df.sort_values(by="LapTime").reset_index(drop=True) | |
| df["LapTime"] = df["LapTime"].round(3) | |
| df["Diff"] = (df["LapTime"] - df["LapTime"].min()).round(3) | |
| teams = laps[["Driver", "Team"]].drop_duplicates().reset_index(drop=True) | |
| # join teams and df | |
| df = df.merge(teams, on="Driver", how="left") | |
| car_colors = utils.team_colors(year) | |
| df["fill"] = df["Team"].map(car_colors) | |
| df_json = df.to_dict("records") | |
| # save the data to the database | |
| for record in df.to_dict("records"): | |
| race_pace = models.RacePace(**record) | |
| db.add(race_pace) | |
| db.commit() | |
| return {"racePace": df_json} | |
| return {"racePace": [dict(race_pace) for race_pace in race_pace_data]} | |
| async def top_speed(year: int, event: str | int, session: str) -> any: | |
| f1session = fastf1.get_session(year, event, session) | |
| f1session.load(telemetry=False, weather=False, messages=False) | |
| laps = f1session.laps | |
| team_colors = utils.team_colors(year) | |
| fastest_speedtrap = ( | |
| laps[["SpeedI1", "SpeedI2", "SpeedST", "SpeedFL"]] | |
| .idxmax(axis=1) | |
| .value_counts() | |
| .index[0] | |
| ) | |
| speed_df = ( | |
| laps[[fastest_speedtrap, "Driver", "Compound", "Team"]] | |
| .groupby("Driver") | |
| .max() | |
| .sort_values(fastest_speedtrap, ascending=False) | |
| .reset_index() | |
| ) | |
| # add team colors to dataframe | |
| speed_df["fill"] = speed_df["Team"].apply(lambda x: team_colors[x]) | |
| # rename fastest speedtrap column to TopSpeed | |
| speed_df.rename(columns={fastest_speedtrap: "TopSpeed"}, inplace=True) | |
| # remove nan values in any column | |
| speed_df = speed_df.dropna() | |
| # Convert to int | |
| speed_df["TopSpeed"] = speed_df["TopSpeed"].astype(int) | |
| speed_dict = speed_df.to_dict(orient="records") | |
| return {"topSpeed": speed_dict} | |
| def get_overtakes(year: int, event: str) -> any: | |
| def get_overtakes_df(year, event): | |
| if year == 2023: | |
| url = "https://docs.google.com/spreadsheets/d/1M4aepPJaIfdqE9oU3L-2CQqKIyubLXG4Q4cqWnyqxp4/export?format=csv" | |
| if year == 2022: | |
| url = "https://docs.google.com/spreadsheets/d/1cuS3B6hk4iQmMaRQoMTcogIInJpavnV7rKuEsiJnEbU/export?format=csv" | |
| if year == 2021: | |
| url = "https://docs.google.com/spreadsheets/d/1ANQnPVkefRmvzrmGvEqXoqQ4dBfgcI_R9FPg-0BcM34/export?format=csv" | |
| if year == 2020: | |
| url = "https://docs.google.com/spreadsheets/d/1eG9WTkXKzFT4NMh-WqHOMs5G0UuPGnb6wP4CnFD8uzY/export?format=csv" | |
| if year == 2019: | |
| url = "https://docs.google.com/spreadsheets/d/10nHg7BIs5ySh_dE9uuIz2lq-gRWcg02tIMr0EPgPvJs/export?format=csv" | |
| if year == 2018: | |
| url = "https://docs.google.com/spreadsheets/d/1MyAwQdczccdca_FAIiZKkqZNauNh3ts99JZ278S2OKc/export?format=csv" | |
| response = requests.get(url, timeout=10) | |
| df = pd.read_csv(BytesIO(response.content)) | |
| df = df[["Driver", event]] | |
| # replace NaNs with 0s | |
| df = df.fillna(0) | |
| # convert numbers to ints | |
| df[event] = df[event].astype(int) | |
| # replace event with "overtakes" | |
| df = df.rename(columns={event: "overtakes"}) | |
| return df | |
| def get_overtaken_df(year, event): | |
| if year == 2023: | |
| url = "https://docs.google.com/spreadsheets/d/1wszzx694Ot-mvA5YrFCpy3or37xMgnC0XpE8uNnJLWk/export?format=csv" | |
| if year == 2022: | |
| url = "https://docs.google.com/spreadsheets/d/19_XFDD3BZDIQVkNE4bG6dwuKvMaO4g5HNaUARGaJwhE/export?format=csv" | |
| if year == 2021: | |
| url = "https://docs.google.com/spreadsheets/d/1dQBHnd3AXEPNH5I75cjbzAAzi9ipqGk3v9eZT9eYKS4/export?format=csv" | |
| if year == 2020: | |
| url = "https://docs.google.com/spreadsheets/d/1snyntPMxYH4_KHSRI96AwBoJQrPbX6OanJAcqbYyW-Y/export?format=csv" | |
| if year == 2019: | |
| url = "https://docs.google.com/spreadsheets/d/11FfFkXErJg7F22iVwJo9XfLFAWucMBVlzL1qUGWxM3s/export?format=csv" | |
| if year == 2018: | |
| url = "https://docs.google.com/spreadsheets/d/1XJXAEyRpRS_UwLHzEtN2PdIaFJYGWSN6ypYN8Ecwp9A/export?format=csv" | |
| response = requests.get(url, timeout=10) | |
| df = pd.read_csv(BytesIO(response.content)) | |
| df = df[["Driver", event]] | |
| # replace NaNs with 0s | |
| df = df.fillna(0) | |
| # convert numbers to ints | |
| df[event] = df[event].astype(int) | |
| df = df.rename(columns={event: "overtaken"}) | |
| return df | |
| overtakes = get_overtakes_df(year, event) | |
| overtaken = get_overtaken_df(year, event) | |
| df = overtakes.merge(overtaken, on="Driver") | |
| # remove drivers with 0 overtakes and 0 overtaken | |
| df = df[(df["overtakes"] != 0) | (df["overtaken"] != 0)] | |
| # sort in the decreasing order of overtakes | |
| df = df.sort_values( | |
| by=["overtakes", "overtaken"], ascending=[False, True] | |
| ).reset_index(drop=True) | |
| # convert to dictionary | |
| df_dict = df.to_dict(orient="records") | |
| return {"overtakes": df_dict} | |
| async def fastest_lap(year: int, event: str | int, session: str) -> any: | |
| f1session = fastf1.get_session(year, event, session) | |
| f1session.load(telemetry=False, weather=False, messages=False) | |
| laps = f1session.laps | |
| drivers = pd.unique(laps["Driver"]) | |
| list_fastest_laps = list() | |
| for drv in drivers: | |
| drvs_fastest_lap = laps.pick_driver(drv).pick_fastest() | |
| list_fastest_laps.append(drvs_fastest_lap) | |
| df = ( | |
| fastf1.core.Laps(list_fastest_laps) | |
| .sort_values(by="LapTime") | |
| .reset_index(drop=True) | |
| ) | |
| pole_lap = df.pick_fastest() | |
| df["Diff"] = df["LapTime"] - pole_lap["LapTime"] | |
| car_colors = utils.team_colors(year) | |
| df["fill"] = df["Team"].map(car_colors) | |
| # convert timedelta to float and round to 3 decimal places | |
| df["Diff"] = df["Diff"].dt.total_seconds().round(3) | |
| df = df[["Driver", "LapTime", "Diff", "Team", "fill"]] | |
| # remove nan values in any column | |
| df = df.dropna() | |
| df_json = df.to_dict("records") | |
| return {"fastest": df_json} | |
| # @st.cache_data | |
| async def driver_standings() -> any: | |
| YEAR = 2023 # datetime.datetime.now().year | |
| df = pd.DataFrame( | |
| pd.read_html(f"https://www.formula1.com/en/results.html/{YEAR}/drivers.html")[0] | |
| ) | |
| df = df[["Driver", "PTS", "Car"]] | |
| # reverse the order | |
| df = df.sort_values(by="PTS", ascending=True) | |
| # in Driver column only keep the last 3 characters | |
| df["Driver"] = df["Driver"].str[:-5] | |
| # add colors to the dataframe | |
| car_colors = utils.team_colors(YEAR) | |
| df["fill"] = df["Car"].map(car_colors) | |
| # remove rows where points is 0 | |
| df = df[df["PTS"] != 0] | |
| df.reset_index(inplace=True, drop=True) | |
| df.rename(columns={"PTS": "Points"}, inplace=True) | |
| return {"WDC": df.to_dict("records")} | |
| # @st.cache_data | |
| async def root(): | |
| return HTMLResponse( | |
| content="""<iframe src="https://tracinginsights-f1-analysis.hf.space" frameborder="0" style="width:100%; height:100%;" scrolling="yes" allowfullscreen:"yes"></iframe>""", | |
| status_code=200, | |
| ) | |
| # @st.cache_data | |
| async def years_available() -> any: | |
| # make a list from 2018 to current year | |
| current_year = datetime.datetime.now().year | |
| years = list(range(2018, current_year + 1)) | |
| # reverse the list to get the latest year first | |
| years.reverse() | |
| years = [{"label": str(year), "value": year} for year in years] | |
| return {"years": years} | |
| # format for events {"events":[{"label":"Saudi Arabian Grand Prix","value":2},{"label":"Bahrain Grand Prix","value":1},{"label":"Pre-Season Testing","value":"t1"}]} | |
| # @st.cache_data | |
| async def events_available(year: int) -> any: | |
| # get events available for a given year | |
| data = utils.LatestData(year) | |
| events = data.get_events() | |
| events = [{"label": event, "value": event} for i, event in enumerate(events)] | |
| events.reverse() | |
| return {"events": events} | |
| # format for sessions {"sessions":[{"label":"FP1","value":"FP1"},{"label":"FP2","value":"FP2"},{"label":"FP3","value":"FP3"},{"label":"Qualifying","value":"Q"},{"label":"Race","value":"R"}]} | |
| # @st.cache_data | |
| async def sessions_available(year: int, event: str | int) -> any: | |
| # get sessions available for a given year and event | |
| data = utils.LatestData(year) | |
| sessions = data.get_sessions(event) | |
| sessions = [{"label": session, "value": session} for session in sessions] | |
| return {"sessions": sessions} | |
| # format for drivers {"drivers":[{"color":"#fff500","label":"RIC","value":"RIC"},{"color":"#ff8700","label":"NOR","value":"NOR"},{"color":"#c00000","label":"VET","value":"VET"},{"color":"#0082fa","label":"LAT","value":"LAT"},{"color":"#787878","label":"GRO","value":"GRO"},{"color":"#ffffff","label":"GAS","value":"GAS"},{"color":"#f596c8","label":"STR","value":"STR"},{"color":"#787878","label":"MAG","value":"MAG"},{"color":"#0600ef","label":"ALB","value":"ALB"},{"color":"#ffffff","label":"KVY","value":"KVY"},{"color":"#fff500","label":"OCO","value":"OCO"},{"color":"#0600ef","label":"VER","value":"VER"},{"color":"#00d2be","label":"HAM","value":"HAM"},{"color":"#ff8700","label":"SAI","value":"SAI"},{"color":"#00d2be","label":"BOT","value":"BOT"},{"color":"#960000","label":"GIO","value":"GIO"}]} | |
| # @st.cache_data | |
| async def get_strategy(year: int, event: str | int) -> any: | |
| f1session = fastf1.get_session(year, event, "R") | |
| f1session.load(telemetry=False, weather=False, messages=False) | |
| laps = f1session.laps | |
| drivers_list = pd.unique(laps["Driver"]) | |
| drivers = pd.DataFrame(drivers_list, columns=["Driver"]) | |
| drivers["FinishOrder"] = drivers.index + 1 | |
| # Get the LapNumber of the first lap of each stint | |
| first_lap = ( | |
| laps[["Driver", "Stint", "Compound", "LapNumber"]] | |
| .groupby(["Driver", "Stint", "Compound"]) | |
| .first() | |
| .reset_index() | |
| ) | |
| # Add FinishOrder to first_lap | |
| first_lap = pd.merge(first_lap, drivers, on="Driver") | |
| # change LapNumber to LapStart | |
| first_lap = first_lap.rename(columns={"LapNumber": "LapStart"}) | |
| # reduce the lapstart by 1 | |
| first_lap["LapStart"] = first_lap["LapStart"] - 1 | |
| # find the last lap of each stint | |
| last_lap = ( | |
| laps[["Driver", "Stint", "Compound", "LapNumber"]] | |
| .groupby(["Driver", "Stint", "Compound"]) | |
| .last() | |
| .reset_index() | |
| ) | |
| # change LapNumber to LapEnd | |
| last_lap = last_lap.rename(columns={"LapNumber": "LapEnd"}) | |
| # combine first_lap and last_lap | |
| stint_laps = pd.merge(first_lap, last_lap, on=["Driver", "Stint", "Compound"]) | |
| # to cover for outliers | |
| stint_laps["fill"] = "white" | |
| stint_laps["fill"] = stint_laps["Compound"].map( | |
| { | |
| "SOFT": "red", | |
| "MEDIUM": "yellow", | |
| "HARD": "white", | |
| "INTERMEDIATE": "blue", | |
| "WET": "green", | |
| } | |
| ) | |
| # sort by FinishOrder | |
| stint_laps = stint_laps.sort_values(by=["FinishOrder"], ascending=[True]) | |
| stint_laps_dict = stint_laps.to_dict("records") | |
| return {"strategy": stint_laps_dict} | |
| async def lap_chart( | |
| year: int, | |
| event: str | int, | |
| session: str, | |
| ) -> any: | |
| ergast = Ergast() | |
| race_names_df = ergast.get_race_schedule(season=year, result_type="pandas") | |
| event_number = race_names_df[race_names_df["raceName"] == event]["round"].values[0] | |
| drivers_df = ergast.get_driver_info( | |
| season=year, round=event_number, result_type="pandas" | |
| ) | |
| laptimes_df = ergast.get_lap_times( | |
| season=year, round=event_number, result_type="pandas", limit=2000 | |
| ).content[0] | |
| laptimes_df = pd.merge(laptimes_df, drivers_df, how="left", on="driverId") | |
| results_df = ergast.get_race_results( | |
| season=year, round=event_number, result_type="pandas" | |
| ).content[0] | |
| results_df = results_df[["driverCode", "constructorName"]] | |
| # merge results_df on laptime_df | |
| laptimes_df = pd.merge(laptimes_df, results_df, how="left", on="driverCode") | |
| team_colors = utils.team_colors(year) | |
| # add team_colors to laptimes_df | |
| laptimes_df["fill"] = laptimes_df["constructorName"].map(team_colors) | |
| # rename number as x and position as y | |
| laptimes_df.rename( | |
| columns={"number": "x", "position": "y", "driverCode": "id"}, inplace=True | |
| ) | |
| lap_chart_data = [] | |
| for driver in laptimes_df["id"].unique(): | |
| data = laptimes_df[laptimes_df["id"] == driver] | |
| fill = data["fill"].values[0] | |
| data = data[["x", "y"]] | |
| data_dict = data.to_dict(orient="records") | |
| driver_dict = {"id": driver, "fill": fill, "data": data_dict} | |
| # add this to all_data | |
| lap_chart_data.append(driver_dict) | |
| lap_chart_dict = {"lapChartData": lap_chart_data} | |
| return lap_chart_dict | |
| async def session_drivers(year: int, event: str | int, session: str) -> any: | |
| # get drivers available for a given year, event and session | |
| f1session = fastf1.get_session(year, event, session) | |
| f1session.load(telemetry=False, weather=False, messages=False) | |
| laps = f1session.laps | |
| team_colors = utils.team_colors(year) | |
| # add team_colors dict to laps on Team column | |
| laps["color"] = laps["Team"].map(team_colors) | |
| unique_drivers = laps["Driver"].unique() | |
| drivers = [ | |
| { | |
| "color": laps[laps.Driver == driver].color.iloc[0], | |
| "label": driver, | |
| "value": driver, | |
| } | |
| for driver in unique_drivers | |
| ] | |
| return {"drivers": drivers} | |
| async def get_driver_laps_data(year: int, event: str | int, session: str) -> any: | |
| # get drivers available for a given year, event and session | |
| f1session = fastf1.get_session(year, event, session) | |
| f1session.load(telemetry=False, weather=False, messages=False) | |
| laps = f1session.laps | |
| team_colors = utils.team_colors(year) | |
| # add team_colors dict to laps on Team column | |
| laps["color"] = laps["Team"].map(team_colors) | |
| # combine Driver and LapNumber as a new column | |
| laps["label"] = ( | |
| laps["Driver"] | |
| + "-" | |
| + laps["LapNumber"].astype(int).astype(str) | |
| + "-" | |
| + str(year) | |
| + "-" | |
| + event | |
| + "-" | |
| + session | |
| ) | |
| laps["value"] = ( | |
| laps["Driver"] | |
| + "-" | |
| + laps["LapNumber"].astype(int).astype(str) | |
| + "-" | |
| + str(year) | |
| + "-" | |
| + event | |
| + "-" | |
| + session | |
| ) | |
| laps = laps[["value", "label", "color"]] | |
| driver_laps_dict = laps.to_dict("records") | |
| return {"laps": driver_laps_dict} | |
| # format for chartData {"chartData":[{"lapnumber":1},{ | |
| # "VER":91.564, | |
| # "VER_compound":"SOFT", | |
| # "VER_compound_color":"#FF5733", | |
| # "lapnumber":2 | |
| # },{"lapnumber":3},{"VER":90.494,"VER_compound":"SOFT","VER_compound_color":"#FF5733","lapnumber":4},{"lapnumber":5},{"VER":90.062,"VER_compound":"SOFT","VER_compound_color":"#FF5733","lapnumber":6},{"lapnumber":7},{"VER":89.815,"VER_compound":"SOFT","VER_compound_color":"#FF5733","lapnumber":8},{"VER":105.248,"VER_compound":"SOFT","VER_compound_color":"#FF5733","lapnumber":9},{"lapnumber":10},{"VER":89.79,"VER_compound":"SOFT","VER_compound_color":"#FF5733","lapnumber":11},{"VER":145.101,"VER_compound":"SOFT","VER_compound_color":"#FF5733","lapnumber":12},{"lapnumber":13},{"VER":89.662,"VER_compound":"SOFT","VER_compound_color":"#FF5733","lapnumber":14},{"lapnumber":15},{"VER":89.617,"VER_compound":"SOFT","VER_compound_color":"#FF5733","lapnumber":16},{"lapnumber":17},{"VER":140.717,"VER_compound":"SOFT","VER_compound_color":"#FF5733","lapnumber":18}]} | |
| # @st.cache_data | |
| async def laps_data(year: int, event: str | int, session: str, driver: str) -> any: | |
| # get drivers available for a given year, event and session | |
| f1session = fastf1.get_session(year, event, session) | |
| f1session.load(telemetry=False, weather=False, messages=False) | |
| laps = f1session.laps | |
| team_colors = utils.team_colors(year) | |
| # add team_colors dict to laps on Team column | |
| drivers = laps.Driver.unique() | |
| # for each driver in drivers, get the Team column from laps and get the color from team_colors dict | |
| drivers = [ | |
| { | |
| "color": team_colors[laps[laps.Driver == driver].Team.iloc[0]], | |
| "label": driver, | |
| "value": driver, | |
| } | |
| for driver in drivers | |
| ] | |
| driver_laps = laps.pick_driver(driver) | |
| driver_laps["LapTime"] = driver_laps["LapTime"].dt.total_seconds() | |
| # remove rows where LapTime is null | |
| driver_laps = driver_laps[driver_laps.LapTime.notnull()] | |
| compound_colors = { | |
| "SOFT": "#FF0000", | |
| "MEDIUM": "#FFFF00", | |
| "HARD": "#FFFFFF", | |
| "INTERMEDIATE": "#00FF00", | |
| "WET": "#088cd0", | |
| } | |
| driver_laps_data = [] | |
| for _, row in driver_laps.iterrows(): | |
| if row["LapTime"] > 0: | |
| lap = { | |
| f"{driver}": row["LapTime"], | |
| f"{driver}_compound": row["Compound"], | |
| f"{driver}_compound_color": compound_colors[row["Compound"]], | |
| "lapnumber": row["LapNumber"], | |
| } | |
| else: | |
| lap = {"lapnumber": row["LapNumber"]} | |
| driver_laps_data.append(lap) | |
| return {"chartData": driver_laps_data} | |
| async def get_laps_data(year: int, event: str | int, session: str, driver: str) -> any: | |
| # get drivers available for a given year, event and session | |
| f1session = fastf1.get_session(year, event, session) | |
| f1session.load(telemetry=False, weather=False, messages=False) | |
| laps = f1session.laps | |
| team_colors = utils.team_colors(year) | |
| # add team_colors dict to laps on Team column | |
| drivers = laps.Driver.unique() | |
| # for each driver in drivers, get the Team column from laps and get the color from team_colors dict | |
| drivers = [ | |
| { | |
| "color": team_colors[laps[laps.Driver == driver].Team.iloc[0]], | |
| "label": driver, | |
| "value": driver, | |
| } | |
| for driver in drivers | |
| ] | |
| driver_laps = laps.pick_driver(driver) | |
| driver_laps["LapTime"] = driver_laps["LapTime"].dt.total_seconds() | |
| driver_laps = driver_laps[["Driver", "LapTime", "LapNumber", "Compound"]] | |
| # remove rows where LapTime is null | |
| driver_laps = driver_laps[driver_laps.LapTime.notnull()] | |
| driver_laps_dict = driver_laps.to_dict("records") | |
| return {"chartData": driver_laps_dict} | |
| # @st.cache_data | |
| async def telemetry_data( | |
| year: int, event: str | int, session: str, driver: str, lap_number: int | |
| ) -> any: | |
| f1session = fastf1.get_session(year, event, session) | |
| f1session.load(telemetry=True, weather=False, messages=False) | |
| laps = f1session.laps | |
| driver_laps = laps.pick_driver(driver) | |
| driver_laps["LapTime"] = driver_laps["LapTime"].dt.total_seconds() | |
| # get the telemetry for lap_number | |
| selected_lap = driver_laps[driver_laps.LapNumber == lap_number] | |
| telemetry = selected_lap.get_telemetry() | |
| lon_acc, lat_acc = accelerations.compute_accelerations(telemetry) | |
| telemetry["lon_acc"] = lon_acc | |
| telemetry["lat_acc"] = lat_acc | |
| telemetry["Time"] = telemetry["Time"].dt.total_seconds() | |
| laptime = selected_lap.LapTime.values[0] | |
| data_key = f"{driver} - Lap {int(lap_number)} - {year} {session} [laptime]" | |
| telemetry["DRS"] = telemetry["DRS"].apply(lambda x: 1 if x in [10, 12, 14] else 0) | |
| brake_tel = [] | |
| drs_tel = [] | |
| gear_tel = [] | |
| rpm_tel = [] | |
| speed_tel = [] | |
| throttle_tel = [] | |
| time_tel = [] | |
| track_map = [] | |
| lon_acc_tel = [] | |
| lat_acc_tel = [] | |
| for _, row in telemetry.iterrows(): | |
| brake = { | |
| "x": row["Distance"], | |
| "y": row["Brake"], | |
| } | |
| brake_tel.append(brake) | |
| drs = { | |
| "x": row["Distance"], | |
| "y": row["DRS"], | |
| } | |
| drs_tel.append(drs) | |
| gear = { | |
| "x": row["Distance"], | |
| "y": row["nGear"], | |
| } | |
| gear_tel.append(gear) | |
| rpm = { | |
| "x": row["Distance"], | |
| "y": row["RPM"], | |
| } | |
| rpm_tel.append(rpm) | |
| speed = { | |
| "x": row["Distance"], | |
| "y": row["Speed"], | |
| } | |
| speed_tel.append(speed) | |
| throttle = { | |
| "x": row["Distance"], | |
| "y": row["Throttle"], | |
| } | |
| throttle_tel.append(throttle) | |
| time = { | |
| "x": row["Distance"], | |
| "y": row["Time"], | |
| } | |
| time_tel.append(time) | |
| lon_acc = { | |
| "x": row["Distance"], | |
| "y": row["lon_acc"], | |
| } | |
| lon_acc_tel.append(lon_acc) | |
| lat_acc = { | |
| "x": row["Distance"], | |
| "y": row["lat_acc"], | |
| } | |
| lat_acc_tel.append(lat_acc) | |
| track = { | |
| "x": row["X"], | |
| "y": row["Y"], | |
| } | |
| track_map.append(track) | |
| telemetry_data = { | |
| "telemetryData": { | |
| "brake": brake_tel, | |
| "dataKey": data_key, | |
| "drs": drs_tel, | |
| "gear": gear_tel, | |
| "rpm": rpm_tel, | |
| "speed": speed_tel, | |
| "throttle": throttle_tel, | |
| "time": time_tel, | |
| "lon_acc": lon_acc_tel, | |
| "lat_acc": lat_acc_tel, | |
| "trackMap": track_map, | |
| } | |
| } | |
| return telemetry_data | |