Skip to main content
The models module provides object-oriented interfaces for working with F1 data. These classes wrap DataFrames and provide convenient methods for common operations.

Laps

A collection of lap data, typically accessed via session.laps or driver.laps. Inherits from pandas DataFrame with additional filtering methods.

Properties

session
Session
Reference to the parent session object.

Methods

pick_driver(identifier)

def pick_driver(identifier: str | int | dict) -> Laps
Filter laps for a specific driver. Accepts driver code, number, or dict with driver info. Example:
laps = session.laps
ver_laps = laps.pick_driver("VER")
# Also works with driver number
ver_laps = laps.pick_driver(1)

pick_drivers(identifiers)

def pick_drivers(identifiers: list) -> Laps
Filter laps for multiple drivers. Example:
top_three = laps.pick_drivers(["VER", "HAM", "LEC"])

pick_fastest(only_by_time=False)

def pick_fastest(only_by_time: bool = False) -> Lap | None
Get the single fastest lap from the collection. Returns None if no valid laps found. Example:
fastest = session.laps.pick_fastest()
if fastest is not None:
    print(f"Fastest lap: {fastest['LapTime']:.3f}s by {fastest['Driver']}")

pick_quicklaps(threshold=1.07)

def pick_quicklaps(threshold: float = 1.07) -> Laps
Filter laps within a percentage of the fastest lap time (default 107%). Example:
# Get all laps within 107% of fastest
quick_laps = laps.pick_quicklaps(threshold=1.07)

pick_tyre(compound) / pick_compounds(compounds)

def pick_tyre(compound: str) -> Laps
def pick_compounds(compounds: list[str]) -> Laps
Filter laps by tire compound. Example:
soft_laps = laps.pick_tyre("SOFT")
# Multiple compounds
slick_laps = laps.pick_compounds(["SOFT", "MEDIUM", "HARD"])

pick_lap(lap_number) / pick_laps(laps)

def pick_lap(lap_number: int) -> Laps
def pick_laps(laps: int | list | slice) -> Laps
Filter by lap number(s). Supports integers, lists, and slices. Example:
lap_10 = laps.pick_lap(10)
# Multiple laps
laps_10_to_20 = laps.pick_laps(slice(10, 20))
# Or specific laps
laps_list = laps.pick_laps([1, 5, 10, 15])

pick_team(name) / pick_teams(names)

def pick_team(name: str) -> Laps
def pick_teams(names: list[str]) -> Laps
Filter laps by team name. Example:
rbr_laps = laps.pick_team("Red Bull Racing")

pick_track_status(status, how="equals")

def pick_track_status(status: str, how: str = "equals") -> Laps
Filter by track status. Use how="contains" for partial matching. Example:
# Yellow flag laps
yellow_laps = laps.pick_track_status("4", how="contains")

pick_wo_box() / pick_box_laps(which="both")

def pick_wo_box() -> Laps
def pick_box_laps(which: str = "both") -> Laps
Filter laps by pit stop activity. which can be “in”, “out”, or “both”. Example:
# Laps without pit stops
no_pit = laps.pick_wo_box()
# Pit in laps only
pit_in = laps.pick_box_laps(which="in")

pick_not_deleted() / pick_accurate()

def pick_not_deleted() -> Laps
def pick_accurate() -> Laps
Filter for valid laps (not deleted) or accurate laps only. Example:
valid_laps = laps.pick_not_deleted().pick_accurate()

get_telemetry() / telemetry

def get_telemetry() -> Telemetry
@property
def telemetry(self) -> Telemetry
Get telemetry data for all laps. Only works for single-driver laps. get_telemetry() includes driver-ahead channels. Example:
ver_laps = laps.pick_driver("VER")
tel = ver_laps.telemetry

iterlaps(require=None)

def iterlaps(require: list[str] | None = None) -> Generator
Iterate over laps with optional required columns. Skips laps with null values in required columns. Example:
for lap_result in laps.iterlaps(require=["LapTime", "Driver"]):
    print(f"Lap {lap_result.lap['LapNumber']}: {lap_result.lap['LapTime']}")

split_qualifying_sessions()

def split_qualifying_sessions() -> tuple[Laps, Laps, Laps]
Returns tuple of (Q1, Q2, Q3) laps. Note: tif1 doesn’t split by session, returns copies for compatibility. Example:
q1, q2, q3 = laps.split_qualifying_sessions()

Lap

Represents a single lap with access to telemetry data. Inherits from pandas Series.

Properties

lap_number
int
The lap number (from LapNumber column).
driver
str
The 3-letter driver code (from Driver column).
telemetry
Telemetry
High-frequency telemetry data for this lap. Loaded lazily on first access. Returns empty Telemetry if not found.
session
Session
Reference to the parent session.

Methods

get_telemetry()

def get_telemetry() -> Telemetry
Explicitly load telemetry data with driver-ahead channels. Same as accessing the telemetry property but includes additional channels. Example:
lap = driver.get_lap(19)
tel = lap.get_telemetry()
print(tel[["Time", "Speed", "Throttle", "DriverAhead"]].head())

get_car_data() / get_pos_data()

def get_car_data(**kwargs) -> Telemetry
def get_pos_data(**kwargs) -> Telemetry
Aliases for getting telemetry data (FastF1 compatibility). Example:
car_data = lap.get_car_data()

get_weather_data()

def get_weather_data() -> Series
Get weather data for this lap (returns empty Series).

Driver

Represents a driver’s performance within a session. Inherits from pandas Series with driver metadata.

Properties

driver
str
The 3-letter driver code (e.g., “VER”). Set as attribute, not in Series data.
DriverNumber
str
The car number (e.g., “1”, “33”). Available in Series data.
Abbreviation
str
Driver abbreviation (same as driver code). Available in Series data.
TeamName
str
Full team name. Available in Series data.
TeamColor
str
Team color hex code. Available in Series data.
FirstName
str
Driver’s first name. Available in Series data.
LastName
str
Driver’s last name. Available in Series data.
FullName
str
Driver’s full name. Available in Series data.
HeadshotUrl
str
URL to driver headshot image. Available in Series data.
laps
Laps | DataFrame
All laps completed by this driver. Loaded lazily. Returns Laps object (pandas) or DataFrame (polars).
session
Session
Reference to the parent session.

Methods

get_lap(lap_number)

def get_lap(lap_number: int) -> Lap
Get a specific lap by number. Parameters:
  • lap_number: The lap number to retrieve (must be positive integer).
Returns:
  • Lap object for the specified lap.
Raises:
  • LapNotFoundError: If the lap doesn’t exist for this driver.
  • ValueError: If lap_number is invalid.
Example:
ver = session.get_driver("VER")
lap_19 = ver.get_lap(19)
print(f"Lap {lap_19.lap_number}: {lap_19['LapTime']}")

get_fastest_lap()

def get_fastest_lap() -> DataFrame
Get this driver’s fastest lap as a single-row DataFrame. Returns empty DataFrame if no valid laps found. Example:
fastest = ver.get_fastest_lap()
if not fastest.empty:
    print(f"Fastest: {fastest['LapTime'].iloc[0]:.3f}s")

get_fastest_lap_tel()

def get_fastest_lap_tel() -> DataFrame
Get telemetry for this driver’s fastest lap. Returns empty DataFrame if not found. Returns:
  • Telemetry DataFrame with columns: Time, Distance, Speed, RPM, nGear, Throttle, Brake, DRS, X, Y, Z, Driver, LapNumber.
Example:
fastest_tel = ver.get_fastest_lap_tel()
if not fastest_tel.empty:
    print(f"Max speed: {fastest_tel['Speed'].max()} km/h")

Telemetry

High-frequency data recorded throughout a lap. Inherits from pandas DataFrame with additional slicing and analysis methods.

Properties

session
Session
Reference to the parent session.
driver
str
Driver code for this telemetry data.

Available Columns

ColumnTypeUnitDescription
TimetimedeltaSecondsTime from lap start (timedelta64[ns])
DistancefloatMetersDistance from lap start
Speedfloatkm/hCurrent speed
RPMintRPMEngine revolutions per minute
nGearint-Current gear (1-8)
Throttlefloat%Throttle position (0-100)
Brakebool-Brake pedal pressed
DRSint-DRS status (0=Off, 10+=On)
X, Y, ZfloatMeters3D position coordinates
Driverstr-Driver code
LapNumberint-Lap number

Methods

slice_by_time(start_time, end_time, pad=0, pad_side="both", interpolate_edges=False)

def slice_by_time(start_time, end_time, pad: int = 0,
                  pad_side: str = "both",
                  interpolate_edges: bool = False) -> Telemetry
Slice telemetry by time window. Example:
# Get first 10 seconds
first_10s = tel.slice_by_time(0, 10)

slice_by_lap(ref_laps, pad=0, pad_side="both", interpolate_edges=False)

def slice_by_lap(ref_laps, pad: int = 0,
                 pad_side: str = "both",
                 interpolate_edges: bool = False) -> Telemetry
Slice telemetry by lap reference (Lap or Laps object). Example:
lap = driver.get_lap(19)
tel = session_telemetry.slice_by_lap(lap)

slice_by_mask(mask, pad=0, pad_side="both")

def slice_by_mask(mask, pad: int = 0, pad_side: str = "both") -> Telemetry
Slice telemetry using a boolean mask. Example:
# Get high-speed sections
high_speed_mask = tel["Speed"] > 300
high_speed_tel = tel.slice_by_mask(high_speed_mask)

add_distance() / integrate_distance()

def add_distance() -> Telemetry
def integrate_distance() -> Series
Calculate distance from speed and time. add_distance() adds Distance column, integrate_distance() returns Series. Example:
tel_with_dist = tel.add_distance()

add_relative_distance()

def add_relative_distance() -> Telemetry
Add RelativeDistance column (0-1 normalized distance). Example:
tel_rel = tel.add_relative_distance()

add_driver_ahead() / calculate_driver_ahead()

def add_driver_ahead() -> Telemetry
def calculate_driver_ahead() -> tuple[Series, Series]
Add DriverAhead and DistanceToDriverAhead columns. Example:
tel_with_ahead = tel.add_driver_ahead()

add_track_status()

def add_track_status() -> Telemetry
Add TrackStatus column (defaults to “1” if not present). Example:
tel_with_status = tel.add_track_status()

fill_missing()

def fill_missing() -> Telemetry
Interpolate missing values in numeric columns. Example:
tel_filled = tel.fill_missing()

merge_channels(other, **kwargs)

def merge_channels(other, **kwargs) -> Telemetry
Merge telemetry from another source using time-based alignment. Example:
merged = tel1.merge_channels(tel2)

resample_channels(rule="1S", **kwargs)

def resample_channels(rule: str = "1S", **kwargs) -> Telemetry
Resample telemetry to a different frequency. Example:
# Resample to 1 second intervals
resampled = tel.resample_channels(rule="1S")

Basic Usage

lap = driver.get_lap(19)
tel = lap.telemetry

# Filter to high-speed sections
high_speed = tel[tel["Speed"] > 300]

# Find maximum speed
max_speed = tel["Speed"].max()

# Plot speed trace
import matplotlib.pyplot as plt
plt.plot(tel["Distance"], tel["Speed"])
plt.show()

SessionResults

Contains race results and final positions. Inherits from pandas DataFrame.

Properties

session
Session
Reference to the parent session.

Available Columns

ColumnDescription
PositionFinal position (1-20)
Driver3-letter driver code
TeamTeam name
PointsChampionship points earned
StatusFinish status (Finished, +1 Lap, Retired, etc.)
TimeTotal race time or gap to winner
Example:
results = session.results
print(results[["Position", "Driver", "Team", "Points"]])

CircuitInfo

Information about the circuit. Simple dataclass-like object.

Properties

circuit_name
str
Official circuit name.
location
str
City/country location.
circuit_length
float
Track length in meters.

Methods

add_marker_distance(reference_lap)

def add_marker_distance(reference_lap: Lap) -> None
Add distance markers from a reference lap. Example:
circuit = session.get_circuit_info()
fastest_lap = session.laps.pick_fastest()
circuit.add_marker_distance(fastest_lap)

DriverResult

Individual driver’s race result. Inherits from pandas Series.

Properties

session
Session
Reference to the parent session.
Position
int
Final position (available in Series data).
Driver
str
Driver code (available in Series data).
Points
int
Points earned (available in Series data).
Status
str
Finish status (available in Series data).
dnf
bool
Whether the driver did not finish (computed property).
Example:
result = session.results.iloc[0]  # Winner
if isinstance(result, DriverResult):
    print(f"Winner: {result['Driver']}")
    print(f"DNF: {result.dnf}")

Usage Examples

All examples use the 2021 Belgian Grand Prix Race session.

Working with Laps collection

import tif1

session = tif1.get_session(2021, "Belgian Grand Prix", "Race")
laps = session.laps

# Filter by driver using pick_driver
ver_laps = laps.pick_driver("VER")

# Or use DataFrame filtering
ham_laps = laps[laps["Driver"] == "HAM"]

# Get fastest lap
fastest = laps.pick_fastest()
if fastest is not None:
    print(f"Fastest: {fastest['LapTime']} by {fastest['Driver']}")

# Filter by compound
soft_laps = laps.pick_tyre("SOFT")

# Get laps in a specific range using pick_laps
lap_1 = laps.pick_lap(1)
laps_1_to_3 = laps.pick_laps(slice(1, 3))

# Get quick laps (within 107% of fastest)
quick_laps = laps.pick_quicklaps(threshold=1.07)

# Filter by team
rbr_laps = laps.pick_team("Red Bull Racing")

# Iterate over laps
for lap_result in laps.pick_driver("VER").iterlaps():
    print(f"Lap {lap_result.lap['LapNumber']}: {lap_result.lap['LapTime']}")

Working with Driver objects

# Get driver
ver = session.get_driver("VER")

# Access driver info (from Series data)
print(f"Driver: {ver.driver}")  # Attribute
print(f"Full Name: {ver['FullName']}")  # Series data
print(f"Team: {ver['TeamName']}")  # Series data
print(f"Number: {ver['DriverNumber']}")  # Series data

# Get all laps
all_laps = ver.laps

# Get specific lap
lap_1 = ver.get_lap(1)

# Get fastest lap
fastest = ver.get_fastest_lap()
if not fastest.empty:
    print(f"Fastest: {fastest['LapTime'].iloc[0]}")

# Get fastest lap telemetry
fastest_tel = ver.get_fastest_lap_tel()
if not fastest_tel.empty:
    print(f"Max speed: {fastest_tel['Speed'].max()} km/h")

Working with Lap objects

# Get a specific lap
lap = ver.get_lap(1)

# Access lap properties
print(f"Lap {lap.lap_number}")
print(f"Driver: {lap.driver}")
print(f"Lap time: {lap['LapTime']}")  # Access Series data

# Get telemetry (lazy loaded)
tel = lap.telemetry

# Get telemetry with driver-ahead channels
tel_with_ahead = lap.get_telemetry()

# Analyze telemetry
if not tel.empty:
    max_speed = tel["Speed"].max()
    avg_throttle = tel["Throttle"].mean()
    print(f"Max speed: {max_speed} km/h")
    print(f"Avg throttle: {avg_throttle}%")

Working with Telemetry

# Get telemetry
lap = ver.get_lap(1)
tel = lap.telemetry

# Basic analysis
if not tel.empty:
    print(f"Samples: {len(tel)}")
    print(f"Max speed: {tel['Speed'].max()} km/h")
    print(f"Max RPM: {tel['RPM'].max()}")

    # Find braking zones
    braking = tel[tel["Brake"] == True]
    print(f"Braking points: {len(braking)}")

    # DRS usage
    drs_active = tel[tel["DRS"] >= 10]
    print(f"DRS active: {len(drs_active)} samples")

    # Slice by time
    first_10s = tel.slice_by_time(0, 10)

    # Add distance if not present
    tel_with_dist = tel.add_distance()

    # Add driver ahead info
    tel_with_ahead = tel.add_driver_ahead()

    # Resample to 1 second intervals
    resampled = tel.resample_channels(rule="1S")

Type Hints

All models support type hints for better IDE integration.
from tif1 import Session, Driver, Lap, Laps, Telemetry
import tif1

session: Session = tif1.get_session(2021, "Belgian Grand Prix", "Race")
driver: Driver = session.get_driver("VER")
lap: Lap = driver.get_lap(1)

# Model types
laps: Laps = session.laps  # Laps inherits from DataFrame
telemetry: Telemetry = lap.telemetry  # Telemetry inherits from DataFrame

# DataFrame types (for polars)
from pandas import DataFrame
laps_df: DataFrame = session.laps
telemetry_df: DataFrame = lap.telemetry

Summary

The models module provides:
  • Object-oriented interface for F1 data
  • Lazy loading for performance
  • Convenient methods for common operations
  • Type hints for IDE support
  • DataFrame-based data access
Use these classes to write clean, maintainable F1 analysis code.

Core API

Session and Driver

Types

Type definitions

Data Schema

Data structure

Examples

Usage examples
Last modified on March 5, 2026