lapbox.practice

API reference

lapbox.practice

Runs, qualifying simulations and long-run pace.

Takes FastF1’s laps as they come (session.laps), the same after normalize_laps, or snake_case laps (driver, lap_number, lap_time_seconds, …).

Fuel loads are never published. Within one run the car burns fuel at a roughly constant rate, so a long run’s slope can be corrected for it; its absolute pace against another team’s cannot, because the two may have carried very different fuel. Treat cross-team long-run pace as indicative.

Summary

detect_runs
Split a session into runs of consecutive timed laps.
Run
One stretch of consecutive timed laps by one driver.
classify_run
Label a run long_run, quali_sim or other.
session_runs
Every run in the session, classified, grouped by driver.
longest_run_length
The most laps at race pace anyone managed in one run.
representative_mask
Which laps of a run are genuine running rather than cruising, traffic or a practice start.
long_run_pace
Pace, degradation and consistency for one long run.
LongRunPace
A driver’s race pace read from one long run.
MIN_LONG_RUN
Laps at race pace that make a long run.
MAX_QUALI_SIM
The most laps a qualifying simulation has.
QUALI_SIM_CUTOFF
A qualifying simulation’s best is within this multiple of the driver’s session best.
RUN_OUTLIER_CUTOFF
Laps slower than this multiple of the run’s best are not race pace.
FUEL_EFFECT_S_PER_LAP
Seconds a car gains per lap from burning fuel; the same assumed value everywhere in lapbox.

Runs

detect_runsfunction

from lapbox.practice import detect_runs
detect_runs(laps)

Split a session into runs of consecutive timed laps.

Parameters

laps: pd.DataFrame
Driver, lap-number and lap-time columns, and optionally compound and stint: FastF1’s laps (Driver, LapNumber, LapTime), the same with LapTimeSeconds, or snake_case laps.

Returns

list[Run] in driver, then lap order. A run breaks at an untimed lap (in-lap, out-lap, aborted attempt), a gap in lap numbers (the car pitted), a compound change or a stint change. An empty list, with a warning logged, when the driver, lap or time column is missing.

Rundataclass

from lapbox.practice import Run
class Run

One stretch of consecutive timed laps by one driver.

Fields

driver: str
The driver.
compound: str | None
The tyre.
start_lap: int
First lap number.
end_lap: int
Last lap number.
lap_times: list[float]
The run’s lap times (s), in order.
stint: float | None
FastF1’s stint number, when known.

Run.lengthproperty

property
Run.length -> int

Laps in the run.

Run.bestproperty

property
Run.best -> float

The fastest lap (s).

Run.medianproperty

property
Run.median -> float

The median lap (s).

classify_runfunction

from lapbox.practice import classify_run
classify_run(run, session_best=None)

Label a run long_run, quali_sim or other.

Parameters

run: Run
From detect_runs.
session_best: float | None = None
The driver’s fastest lap of the session (s). Without it no short run can be confirmed as a qualifying simulation.

Returns

str

A long run has at least MIN_LONG_RUN (5) laps at race pace: within RUN_OUTLIER_CUTOFF (107 %) of the run’s best. Counting every timed lap is not enough: a qualifying run with its out-lap and cool-down laps is five consecutive timed laps, only one or two of them at pace.

A qualifying simulation is short and fast: at most MAX_QUALI_SIM (3) laps, its best within QUALI_SIM_CUTOFF (102 %) of session_best. Everything else is other.

session_runsfunction

from lapbox.practice import session_runs
session_runs(laps)

Every run in the session, classified, grouped by driver.

Parameters

laps: pd.DataFrame
As for detect_runs.

Returns

dict[str, list[tuple[Run, str]]]: driver → (run, kind) pairs, each run classified against that driver’s best lap of the session.

longest_run_lengthfunction

from lapbox.practice import longest_run_length
longest_run_length(laps)

The most laps at race pace anyone managed in one run.

Parameters

laps: pd.DataFrame
As for detect_runs.

Returns

int: 0 when there are no runs.

Laps are counted as classify_run counts them, so longest_run_length(laps) >= MIN_LONG_RUN exactly when session_runs finds a long run: use it to decide whether a session supports long-run analysis at all. Counting every timed lap instead let 6 of 145 practice sessions (2022–2026) through with no long run in them.

representative_maskfunction

from lapbox.practice import representative_mask
representative_mask(times, cutoff=1.07)

Which laps of a run are genuine running rather than cruising, traffic or a practice start.

Parameters

times: np.ndarray
A run’s lap times (s).
cutoff: float = 1.07
Laps slower than this multiple of the run’s best are dropped.

Returns

np.ndarray of bool, one per lap.

Long-run pace

long_run_pacefunction

from lapbox.practice import long_run_pace
long_run_pace(run, *, cutoff=1.07)

Pace, degradation and consistency for one long run.

Parameters

run: Run
Usually one classify_run labels long_run.
cutoff: float = 1.07
Laps slower than this multiple of the run’s best are dropped first.

Returns

LongRunPace

The laps that survive keep their original positions in the run, so the slope stays a true per-lap rate. The observed slope understates tyre wear because the car gets lighter at the same time; adding FUEL_EFFECT_S_PER_LAP back gives the tyre’s own trend, which — unlike absolute pace — doesn’t depend on how much fuel was on board.

LongRunPacedataclass

from lapbox.practice import LongRunPace
class LongRunPace

A driver’s race pace read from one long run.

Fields

driver: str
The driver.
compound: str | None
The tyre.
laps: int
Laps measured (after dropping slow ones).
median_s: float
Median lap time: the headline pace. Fuel load unknown, so indicative.
raw_slope_s_per_lap: float
The observed trend: tyre wear minus fuel burn.
deg_slope_s_per_lap: float
The trend with the fuel effect added back: the tyre’s own.
consistency_s: float
Standard deviation of the measured laps (s).
laps_dropped: int
Laps left out as unrepresentative.

Constants

MIN_LONG_RUNconstant

from lapbox.practice import MIN_LONG_RUN
MIN_LONG_RUN = 5

Laps at race pace that make a long run.

MAX_QUALI_SIMconstant

from lapbox.practice import MAX_QUALI_SIM
MAX_QUALI_SIM = 3

The most laps a qualifying simulation has.

QUALI_SIM_CUTOFFconstant

from lapbox.practice import QUALI_SIM_CUTOFF
QUALI_SIM_CUTOFF = 1.02

A qualifying simulation’s best is within this multiple of the driver’s session best.

RUN_OUTLIER_CUTOFFconstant

from lapbox.practice import RUN_OUTLIER_CUTOFF
RUN_OUTLIER_CUTOFF = 1.07

Laps slower than this multiple of the run’s best are not race pace.

Anchored to the best lap rather than the median: when half a run is compromised the median is contaminated too, and a median-relative cut keeps the very laps it should remove.

FUEL_EFFECT_S_PER_LAPconstant

from lapbox.practice import FUEL_EFFECT_S_PER_LAP
FUEL_EFFECT_S_PER_LAP = 0.048

Seconds a car gains per lap from burning fuel; the same assumed value everywhere in lapbox.

About 1.6 kg of fuel a lap at about 0.03 s per kg. It is assumed, the same for every car and race, not measured — see Limits.

These docs describe lapbox 0.1.0. Something wrong or missing? Open an issue.