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
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
The lap number (from LapNumber column).
The 3-letter driver code (from Driver column).
High-frequency telemetry data for this lap. Loaded lazily on first access. Returns empty Telemetry if not found.
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
The 3-letter driver code (e.g., “VER”). Set as attribute, not in Series data.
The car number (e.g., “1”, “33”). Available in Series data.
Driver abbreviation (same as driver code). Available in Series data.
Full team name. Available in Series data.
Team color hex code. Available in Series data.
Driver’s first name. Available in Series data.
Driver’s last name. Available in Series data.
Driver’s full name. Available in Series data.
URL to driver headshot image. Available in Series data.
All laps completed by this driver. Loaded lazily. Returns Laps object (pandas) or DataFrame (polars).
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
Reference to the parent session.
Driver code for this telemetry data.
Available Columns
| Column | Type | Unit | Description |
|---|
Time | timedelta | Seconds | Time from lap start (timedelta64[ns]) |
Distance | float | Meters | Distance from lap start |
Speed | float | km/h | Current speed |
RPM | int | RPM | Engine revolutions per minute |
nGear | int | - | Current gear (1-8) |
Throttle | float | % | Throttle position (0-100) |
Brake | bool | - | Brake pedal pressed |
DRS | int | - | DRS status (0=Off, 10+=On) |
X, Y, Z | float | Meters | 3D position coordinates |
Driver | str | - | Driver code |
LapNumber | int | - | 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
Reference to the parent session.
Available Columns
| Column | Description |
|---|
Position | Final position (1-20) |
Driver | 3-letter driver code |
Team | Team name |
Points | Championship points earned |
Status | Finish status (Finished, +1 Lap, Retired, etc.) |
Time | Total 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
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
Reference to the parent session.
Final position (available in Series data).
Driver code (available in Series data).
Points earned (available in Series data).
Finish status (available in Series data).
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.
Related Pages
Core API
Session and Driver
Data Schema
Data structure