Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/TracingInsights/tif1/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Driver class in tif1 provides driver-specific access to lap data, telemetry, and metadata. Each driver is represented as a pandas Series containing their information (name, team, number) with methods to access their session data.

Getting Drivers

Driver List

Get a list of all drivers in a session:
import tif1

session = tif1.get_session(2024, "Monaco", "Race")

# Get driver codes as list
drivers = session.drivers
print(drivers)  # ['1', '11', '16', '4', '63', ...]

# Get detailed driver information
drivers_df = session.drivers_df
print(drivers_df[['Driver', 'DriverNumber', 'FirstName', 'LastName', 'Team']])
#   Driver DriverNumber FirstName  LastName              Team
# 0    VER            1       Max  Verstappen  Red Bull Racing
# 1    PER           11    Sergio      Perez   Red Bull Racing
# 2    LEC           16   Charles    Leclerc          Ferrari
# ...

Getting a Specific Driver

Access driver data through the session:
session = tif1.get_session(2024, "Monaco", "Race")

# Method 1: Through laps filtering
ver_laps = session.laps.pick_driver('VER')

# Method 2: Direct driver object (internal API)
driver_info = session._get_driver_info('VER')
print(driver_info)
# {
#     'driver': 'VER',
#     'dn': '1',           # driver number
#     'fn': 'Max',         # first name
#     'ln': 'Verstappen',  # last name
#     'team': 'Red Bull Racing',
#     'tc': '#3671C6',     # team color
#     'url': 'https://...' # headshot URL
# }

Driver Class

Class Definition

From core.py:4960-5020:
class Driver(pd.Series):
    """
    Represents a driver in a session as a pandas Series.

    Args:
        session: Parent Session object
        driver: Driver code (e.g., 'VER', 'HAM')

    Attributes:
        session: Parent Session
        driver: Driver code
        laps: DataFrame with driver's laps
    """

Driver Attributes

Each Driver object contains:
driver = Driver(session, 'VER')

# Metadata (accessed as Series)
print(driver['DriverNumber'])    # '1'
print(driver['Abbreviation'])    # 'VER'
print(driver['TeamName'])        # 'Red Bull Racing'
print(driver['TeamColor'])       # '#3671C6'
print(driver['FirstName'])       # 'Max'
print(driver['LastName'])        # 'Verstappen'
print(driver['FullName'])        # 'Max Verstappen'
print(driver['HeadshotUrl'])     # 'https://...'

# Custom attributes
print(driver.driver)             # 'VER'
print(driver.session.year)       # 2024

Working with Driver Laps

The most common way to work with drivers is through lap filtering:

Get Driver Laps

session = tif1.get_session(2024, "Monaco", "Race")
laps = session.laps

# Get all laps for a driver
ver_laps = laps.pick_driver('VER')
print(f"Verstappen completed {len(ver_laps)} laps")

# Get laps for multiple drivers
top3_laps = laps.pick_drivers(['VER', 'HAM', 'LEC'])
print(f"Top 3 drivers: {len(top3_laps)} total laps")

Driver Lap Analysis

ver_laps = laps.pick_driver('VER')

# Get driver's fastest lap
fastest = ver_laps.pick_fastest()
print(f"Fastest lap: {fastest['LapNumber']} - {fastest['LapTime']}")

# Analyze race pace (exclude pit laps)
race_pace = ver_laps.pick_wo_box().pick_accurate()
avg_lap_time = race_pace['LapTime'].mean()
print(f"Average race pace: {avg_lap_time}")

# Analyze by compound
for compound in ver_laps['Compound'].unique():
    compound_laps = ver_laps.pick_tyre(compound)
    avg_time = compound_laps['LapTime'].mean()
    print(f"{compound}: {avg_time} ({len(compound_laps)} laps)")

Driver-Specific Telemetry

Getting Driver Telemetry

session = tif1.get_session(2024, "Monaco", "Qualifying")
laps = session.laps

# Get Verstappen's fastest lap
ver_fastest = laps.pick_driver('VER').pick_fastest()

# Get telemetry for this lap
tel = ver_fastest.telemetry
print(tel[['Time', 'Speed', 'Throttle', 'Brake', 'nGear']].head())
#        Time  Speed  Throttle  Brake  nGear
# 0  0.000000  285.0      95.0  False      8
# 1  0.012000  286.5      97.0  False      8
# 2  0.024000  288.0      98.0  False      8
# ...

Batch Loading Driver Telemetry

For loading telemetry for multiple drivers efficiently:
session = tif1.get_session(2024, "Monaco", "Qualifying")

# ✅ Fast - parallel loading for all drivers
fastest_tels = session.get_fastest_laps_tels(by_driver=True)
# Returns DataFrame with all drivers' fastest lap telemetry

# ✅ Fast - specific drivers only
top3_tels = session.get_fastest_laps_tels(
    by_driver=True,
    drivers=['VER', 'HAM', 'LEC']
)
The get_fastest_laps_tels() method loads telemetry in parallel, making it 28x faster than sequential loading (11.2s → 0.4s for 19 drivers).

Driver Identification

Tif1 supports multiple ways to identify drivers:

By Driver Code

laps = session.laps

# Using 3-letter code (most common)
ver_laps = laps.pick_driver('VER')
ham_laps = laps.pick_driver('HAM')

By Driver Number

# Using driver number (as string)
ver_laps = laps.pick_driver('1')   # Verstappen
ham_laps = laps.pick_driver('44')  # Hamilton

Normalization

Driver identifiers are automatically normalized:
# All of these work
ver1 = laps.pick_driver('VER')          # Driver code
ver2 = laps.pick_driver('1')            # Driver number (string)
ver3 = laps.pick_driver(1)              # Driver number (int)

# Even dict-like objects
driver_dict = {'driver': 'VER', 'dn': 1}
ver4 = laps.pick_driver(driver_dict)
From core.py:282-306:
@staticmethod
def _normalize_driver_identifier(identifier: Any) -> str:
    """Normalize various driver identifier formats to string."""
    if isinstance(identifier, str | int):
        return str(identifier)
    if isinstance(identifier, dict):
        for key in ('driver', 'Driver', 'Abbreviation', 'dn', 'RacingNumber'):
            value = identifier.get(key)
            if value is not None and str(value).strip():
                return str(value)
    if hasattr(identifier, 'driver'):
        value = identifier.driver
        if value is not None and str(value).strip():
            return str(value)
    return str(identifier)

Driver Comparisons

Comparing Two Drivers

import matplotlib.pyplot as plt

session = tif1.get_session(2024, "Monaco", "Qualifying")
laps = session.laps

# Get fastest laps
ver_fastest = laps.pick_driver('VER').pick_fastest()
ham_fastest = laps.pick_driver('HAM').pick_fastest()

# Get telemetry
ver_tel = ver_fastest.telemetry.add_distance()
ham_tel = ham_fastest.telemetry.add_distance()

# Plot speed comparison
plt.figure(figsize=(12, 6))
plt.plot(ver_tel['Distance'], ver_tel['Speed'], label='VER', color='#3671C6')
plt.plot(ham_tel['Distance'], ham_tel['Speed'], label='HAM', color='#27F4D2')
plt.xlabel('Distance (m)')
plt.ylabel('Speed (km/h)')
plt.title('Speed Comparison - Monaco Q3')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

# Calculate time delta
ver_time = ver_fastest['LapTime'].total_seconds()
ham_time = ham_fastest['LapTime'].total_seconds()
delta = ham_time - ver_time
print(f"Time delta: {delta:.3f}s (HAM {'faster' if delta < 0 else 'slower'})")

Multi-Driver Analysis

session = tif1.get_session(2024, "Monaco", "Race")
laps = session.laps

# Analyze all drivers' pace
import pandas as pd

pace_data = []
for driver in session.drivers:
    driver_laps = laps.pick_driver(driver).pick_wo_box().pick_accurate()
    if len(driver_laps) > 0:
        avg_pace = driver_laps['LapTime'].mean()
        pace_data.append({
            'Driver': driver,
            'AvgPace': avg_pace,
            'Laps': len(driver_laps)
        })

pace_df = pd.DataFrame(pace_data).sort_values('AvgPace')
print(pace_df.head(10))

Driver Results

Access session results and standings:
session = tif1.get_session(2024, "Monaco", "Race")

# Get all results
results = session.results
print(results[['FullName', 'TeamName', 'Position', 'Points']])

# Get specific driver result
ver_result = results[results['Abbreviation'] == 'VER'].iloc[0]
print(f"{ver_result['FullName']}: P{ver_result['Position']}")

# Check DNF status
if ver_result.dnf:
    print(f"{ver_result['FullName']} did not finish")

Common Driver Operations

Get Driver’s Best Sectors

ver_laps = laps.pick_driver('VER')

# Find best sectors
best_s1 = ver_laps['Sector1Time'].min()
best_s2 = ver_laps['Sector2Time'].min()
best_s3 = ver_laps['Sector3Time'].min()

print(f"Best S1: {best_s1}")
print(f"Best S2: {best_s2}")
print(f"Best S3: {best_s3}")
print(f"Theoretical best: {best_s1 + best_s2 + best_s3}")

Track Driver Strategy

ver_laps = laps.pick_driver('VER')

print("Race strategy:")
for stint in ver_laps['Stint'].unique():
    stint_laps = ver_laps[ver_laps['Stint'] == stint]
    
    # Get stint info
    compound = stint_laps['Compound'].iloc[0]
    start_lap = stint_laps['LapNumber'].min()
    end_lap = stint_laps['LapNumber'].max()
    stint_length = end_lap - start_lap + 1
    
    print(f"Stint {int(stint)}: Laps {int(start_lap)}-{int(end_lap)} ({compound}, {stint_length} laps)")

Find Overtakes

ver_laps = laps.pick_driver('VER')

# Track position changes
ver_laps = ver_laps.sort_values('LapNumber')
position_changes = ver_laps['Position'].diff()

# Find overtakes (position improved)
overtakes = ver_laps[position_changes < 0]
print("Overtakes:")
for idx, lap in overtakes.iterrows():
    prev_pos = lap['Position'] - position_changes.loc[idx]
    print(f"Lap {int(lap['LapNumber'])}: P{int(prev_pos)} → P{int(lap['Position'])}")

Analyze Tire Degradation

ver_laps = laps.pick_driver('VER')

# Get final stint on soft tires
soft_stint = ver_laps[ver_laps['Compound'] == 'SOFT']
if len(soft_stint) > 5:
    # Compare first 3 laps vs last 3 laps
    early_pace = soft_stint.head(3)['LapTime'].mean()
    late_pace = soft_stint.tail(3)['LapTime'].mean()
    degradation = (late_pace - early_pace).total_seconds()
    print(f"Tire degradation: {degradation:.2f}s over {len(soft_stint)} laps")

Performance Tips

1. Filter Early

# ✅ Good - filter once, reuse
ver_laps = laps.pick_driver('VER')
ver_race = ver_laps.pick_wo_box().pick_accurate()

# Now use ver_race for multiple operations
avg_pace = ver_race['LapTime'].mean()
fastest = ver_race.pick_fastest()

# ❌ Bad - filter repeatedly
avg_pace = laps.pick_driver('VER').pick_wo_box()['LapTime'].mean()
fastest = laps.pick_driver('VER').pick_wo_box().pick_fastest()

2. Use Batch Operations

# ✅ Fast - batch load telemetry
all_fastest_tels = session.get_fastest_laps_tels(by_driver=True)
ver_tel = all_fastest_tels[all_fastest_tels['Driver'] == 'VER']

# ❌ Slow - load individually
ver_tel = laps.pick_driver('VER').pick_fastest().telemetry

3. Cache Driver Info

# ✅ Good - get drivers once
drivers = session.drivers
for driver in drivers:
    driver_laps = laps.pick_driver(driver)
    # process laps...

# ❌ Bad - repeated property access
for i in range(len(session.drivers)):
    driver = session.drivers[i]  # Re-fetches each time

Sessions

Learn about Session objects and session types

Laps and Telemetry

Working with lap timing and telemetry data

Data Flow

Understand the data loading pipeline

API Reference

Complete Driver API documentation

Build docs developers (and LLMs) love