Skip to content

Commit

Permalink
FIX: incorrect quali session split; closes #605
Browse files Browse the repository at this point in the history
  • Loading branch information
theOehrly committed Oct 6, 2024
1 parent 95f6231 commit 7ad8d30
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
23 changes: 21 additions & 2 deletions fastf1/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3340,13 +3340,32 @@ def split_qualifying_sessions(self) -> list[Optional["Laps"]]:
# add the very last timestamp, to get an end for the last interval
split_times.append(self.session.session_status['Time'].iloc[-1])
laps = [None, None, None]
prev_early = None
for i in range(len(split_times) - 1):
# split by start time instead of end time, because the split times
# that are generated from timing data may not account for crashed
# cars being returned or having a generated lap time that results
# in a late 'Time' value!
laps[i] = self[(self['LapStartTime'] > split_times[i])
& (self['LapStartTime'] < split_times[i + 1])]
cond = ((self['LapStartTime'] > split_times[i])
& (self['LapStartTime'] < split_times[i + 1]))

# if this is Q2 or Q3 and there are left over "early" laps from the
# last session, add them to the current session
if prev_early is not None:
cond |= prev_early

# find laps that "start" early, this happens when cars cross the
# timing beam in the pits before the next quali session starts:
# lap is pit out, starts in current session, ends in next session
is_early = ((self['LapStartTime'] < split_times[i + 1])
& (self['Time'] > split_times[i + 1])
& ~pd.isna(self['PitOutTime']))

# select the laps for the current session, excluding the early laps
laps[i] = self[cond & ~is_early]

prev_early = is_early

if laps[i].empty:
laps[i] = None
return laps
Expand Down
9 changes: 8 additions & 1 deletion fastf1/tests/test_laps.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def test_laps_pick_track_status(reference_laps_data):
@pytest.mark.f1telapi
@pytest.mark.parametrize("source", ["session_status", "timing_data"])
def test_split_quali_laps(source):
session = fastf1.get_session(2023, 2, 'Q')
session = fastf1.get_session(2024, 10, 'Q')
session.load(telemetry=False, weather=False)

if source == "session_status":
Expand All @@ -295,10 +295,17 @@ def test_split_quali_laps(source):

q1, q2, q3 = session.laps.split_qualifying_sessions()

# verify correct number of drivers per session
assert len(q1['DriverNumber'].unique()) == 20
assert len(q2['DriverNumber'].unique()) == 15
assert len(q3['DriverNumber'].unique()) == 10

# verify that the last lap of q1 and q2 session is within the session time
# check for "early lap starts" (car crosses timing beam in pits before next
# session starts) being handled correctly, see #605
assert q1['Time'].max() < pd.Timedelta(hours=0, minutes=40)
assert q2['Time'].max() < pd.Timedelta(hours=1, minutes=3)


@pytest.mark.f1telapi
@pytest.mark.parametrize("source", ["session_status", "timing_data"])
Expand Down

0 comments on commit 7ad8d30

Please sign in to comment.