Skip to content

Commit a373966

Browse files
committed
fix analysis
1 parent 060b1d6 commit a373966

File tree

2 files changed

+42
-63
lines changed

2 files changed

+42
-63
lines changed

telemetry/analyzer.py

+26-52
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ def sector_lap_time(self, sector_df):
4040
# print(f"section_lap_time: {section_lap_time}")
4141
return section_lap_time
4242

43-
def split_sectors(
44-
self, df, threshold=None, min_length_throttle_below_threshold=50, min_distance_between_sectors=50
45-
):
43+
def split_sectors(self, df, threshold=None, min_length_throttle_below_threshold=50, min_distance_between_sectors=50):
4644
logging.debug(f"split_sectors: min_length_throttle_below_threshold: {min_length_throttle_below_threshold}")
4745
logging.debug(f"split_sectors: min_distance_between_sectors: {min_distance_between_sectors}")
4846
if threshold is None:
@@ -63,7 +61,7 @@ def split_sectors(
6361
one_sector = [
6462
{"start": 0, "end": max_distance, "length": max_distance},
6563
]
66-
64+
6765
# Return one sector if we don't have valid start/end points
6866
if len(start) == 0 or len(end) == 0:
6967
logging.error(f"No valid sectors found - threshold: {threshold} min_length: {min_length_throttle_below_threshold}")
@@ -115,9 +113,7 @@ def split_sectors(
115113
# sector["start"] = prev_sector["start"]
116114
prev_sector["end"] = sector["end"]
117115
remove_indices.append(i)
118-
logging.debug(
119-
f"remove sector {i} - {sector['start']}m " + f"too close to previous sector: {distance_between}"
120-
)
116+
logging.debug(f"remove sector {i} - {sector['start']}m " + f"too close to previous sector: {distance_between}")
121117

122118
new_sectors = []
123119
for i, sector in enumerate(sectors):
@@ -174,15 +170,11 @@ def section_df(self, track_df, start, end):
174170

175171
if end < start:
176172
# Wrap around the max_distance
177-
first_part = track_df[
178-
(track_df["DistanceRoundTrack"] >= start) & (track_df["DistanceRoundTrack"] <= max_distance)
179-
]
173+
first_part = track_df[(track_df["DistanceRoundTrack"] >= start) & (track_df["DistanceRoundTrack"] <= max_distance)]
180174
second_part = track_df[(track_df["DistanceRoundTrack"] >= 0) & (track_df["DistanceRoundTrack"] <= end)]
181175
sector_df = pd.concat([first_part, second_part], axis=0).reset_index(drop=True)
182176
else:
183-
sector_df = track_df[
184-
(track_df["DistanceRoundTrack"] >= start) & (track_df["DistanceRoundTrack"] <= end)
185-
].reset_index(drop=True)
177+
sector_df = track_df[(track_df["DistanceRoundTrack"] >= start) & (track_df["DistanceRoundTrack"] <= end)].reset_index(drop=True)
186178

187179
return sector_df
188180

@@ -253,9 +245,7 @@ def extract_window_start_end(self, sector_df, threshold, comparison_operator):
253245
window_start = None
254246

255247
if window_start is not None and not below_threshold.empty:
256-
window_end = below_threshold[below_threshold["DistanceRoundTrack"] > window_start].iloc[0][
257-
"DistanceRoundTrack"
258-
]
248+
window_end = below_threshold[below_threshold["DistanceRoundTrack"] > window_start].iloc[0]["DistanceRoundTrack"]
259249
else:
260250
window_end = None
261251

@@ -357,7 +347,7 @@ def resample_channels(self, lap_df, columns=["Brake", "SpeedMs"], freq=1, max_di
357347
# Early return if DataFrame is empty
358348
if len(lap_df) == 0:
359349
return lap_df
360-
350+
361351
# Check if DistanceRoundTrack exists
362352
if "DistanceRoundTrack" not in lap_df.columns:
363353
logging.error("DistanceRoundTrack column not found in DataFrame")
@@ -406,23 +396,13 @@ def resample_channels(self, lap_df, columns=["Brake", "SpeedMs"], freq=1, max_di
406396
# Handle interpolated columns
407397
if df_interpolate_columns:
408398
source_df = lap_df[df_interpolate_columns + ["DistanceRoundTrack"]]
409-
interp_df = pd.merge_asof(
410-
result_df,
411-
source_df,
412-
on="DistanceRoundTrack",
413-
direction="nearest"
414-
).interpolate("linear")
399+
interp_df = pd.merge_asof(result_df, source_df, on="DistanceRoundTrack", direction="nearest").interpolate("linear")
415400
result_df[df_interpolate_columns] = interp_df[df_interpolate_columns]
416401

417402
# Handle backfill columns
418403
if df_backfill_columns:
419404
source_df = lap_df[df_backfill_columns + ["DistanceRoundTrack"]]
420-
backfill_df = pd.merge_asof(
421-
result_df,
422-
source_df,
423-
on="DistanceRoundTrack",
424-
direction="nearest"
425-
).bfill()
405+
backfill_df = pd.merge_asof(result_df, source_df, on="DistanceRoundTrack", direction="nearest").bfill()
426406
result_df[df_backfill_columns] = backfill_df[df_backfill_columns]
427407

428408
new_df = result_df
@@ -442,18 +422,24 @@ def resample(self, input_df, columns=["Brake", "SpeedMs"], method="nearest", fre
442422
max_distance = int(np.floor(df["DistanceRoundTrack"].max()))
443423
target_rows = int(max_distance / freq)
444424

425+
if target_rows <= 0:
426+
logging.error(f"Invalid target rows: {target_rows} (max_distance: {max_distance}, freq: {freq})")
427+
return input_df
428+
445429
new_distance_round_track = np.linspace(min_distance, max_distance, target_rows)
430+
if len(new_distance_round_track) == 0:
431+
logging.error("Empty distance track array generated")
432+
return input_df
446433

447434
new_distance_round_track = np.round(new_distance_round_track, decimals=2)
448-
new_distance_round_track[0] = max(new_distance_round_track[0], min_distance)
449-
new_distance_round_track[-1] = min(new_distance_round_track[-1], max_distance)
435+
if len(new_distance_round_track) > 0:
436+
new_distance_round_track[0] = max(new_distance_round_track[0], min_distance)
437+
new_distance_round_track[-1] = min(new_distance_round_track[-1], max_distance)
450438

451439
resampled_df = pd.DataFrame({"DistanceRoundTrack": new_distance_round_track})
452440

453441
for column in columns:
454-
interp = interp1d(
455-
df["DistanceRoundTrack"], df[column], kind=method, bounds_error=False, fill_value="extrapolate"
456-
)
442+
interp = interp1d(df["DistanceRoundTrack"], df[column], kind=method, bounds_error=False, fill_value="extrapolate")
457443
interpolated_values = interp(new_distance_round_track)
458444

459445
if np.issubdtype(df[column].dtype, np.integer):
@@ -495,9 +481,7 @@ def distance_speed_lookup_table_non_lin(self, lap):
495481
lap = lap[["DistanceRoundTrack", "CurrentLapTime", "SpeedMs"]].copy()
496482
lap_start = lap["CurrentLapTime"].idxmin()
497483

498-
lap.loc[:lap_start, "CurrentLapTime"] = (
499-
lap.loc[:lap_start, "DistanceRoundTrack"] / lap.loc[:lap_start, "SpeedMs"]
500-
)
484+
lap.loc[:lap_start, "CurrentLapTime"] = lap.loc[:lap_start, "DistanceRoundTrack"] / lap.loc[:lap_start, "SpeedMs"]
501485
lap = lap[["DistanceRoundTrack", "CurrentLapTime", "SpeedMs"]]
502486
lap["DistanceRoundTrack"] = lap["DistanceRoundTrack"].round(1)
503487
lap["CurrentLapTime"] = lap["CurrentLapTime"].round(3)
@@ -617,18 +601,14 @@ def extract_sector_start_end(self, sectors, threshold=0.98, track_length=0, min_
617601
if i == len(sectors) - 1:
618602
end = int((sectors[0]["DistanceRoundTrack"].iloc[0] - delta - 1) % track_length)
619603
else:
620-
end = int(
621-
(sectors[i + 1]["DistanceRoundTrack"].iloc[0] - delta - 1) % track_length
622-
) # Subtract 11 to make the boundaries exactly one meter apart
604+
end = int((sectors[i + 1]["DistanceRoundTrack"].iloc[0] - delta - 1) % track_length) # Subtract 11 to make the boundaries exactly one meter apart
623605

624606
length = int((end - start) % track_length)
625607

626608
# Merge sectors shorter than the threshold with the previous sector
627609
if i > 0 and length < min_length:
628610
sector_start_end[-1]["end"] = end
629-
sector_start_end[-1]["length"] = (
630-
sector_start_end[-1]["end"] - sector_start_end[-1]["start"]
631-
) % track_length
611+
sector_start_end[-1]["length"] = (sector_start_end[-1]["end"] - sector_start_end[-1]["start"]) % track_length
632612
else:
633613
sector_start_end.append({"start": start, "end": end, "length": length})
634614
return sector_start_end
@@ -659,14 +639,10 @@ def local_extrema(self, df, column="Gear", mode="min", points=50):
659639

660640
if mode == "min":
661641
# now find the local minima again
662-
real = min_max[column][
663-
(min_max[column].shift(1) >= min_max[column]) & (min_max[column].shift(-1) > min_max[column])
664-
]
642+
real = min_max[column][(min_max[column].shift(1) >= min_max[column]) & (min_max[column].shift(-1) > min_max[column])]
665643
else:
666644
# now find the local maxima again
667-
real = min_max[column][
668-
(min_max[column].shift(1) <= min_max[column]) & (min_max[column].shift(-1) < min_max[column])
669-
]
645+
real = min_max[column][(min_max[column].shift(1) <= min_max[column]) & (min_max[column].shift(-1) < min_max[column])]
670646

671647
return df.loc[real.index]
672648

@@ -685,9 +661,7 @@ def local_minima_off(self, df, column="Gear"):
685661
min_max = pd.concat([min_max, df.iloc[[0, -1]]])
686662

687663
# now find the local minima again
688-
real_min = min_max[column][
689-
(min_max[column].shift(1) >= min_max[column]) & (min_max[column].shift(-1) > min_max[column])
690-
]
664+
real_min = min_max[column][(min_max[column].shift(1) >= min_max[column]) & (min_max[column].shift(-1) > min_max[column])]
691665
return df.loc[real_min.index]
692666

693667
def extend_lap(self, df, count=2):

telemetry/fast_lap_analyzer.py

+16-11
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,18 @@ def fetch_lap_telemetry(self, max_laps=None):
4040
logging.info("No data found for lap, continuing")
4141
continue
4242
laps_with_telemetry.append(lap)
43-
df = self.preprocess(laps[0])
44-
lap_telemetry.append(df)
45-
counter += 1
46-
if max_laps and counter >= max_laps:
47-
break
43+
try:
44+
df = self.preprocess(laps[0])
45+
if df is not None and not df.empty:
46+
lap_telemetry.append(df)
47+
counter += 1
48+
if max_laps and counter >= max_laps:
49+
break
50+
else:
51+
logging.error("Preprocessing returned empty dataframe")
52+
except Exception as e:
53+
logging.error(f"Error preprocessing lap: {e}")
54+
continue
4855

4956
return lap_telemetry, laps_with_telemetry
5057

@@ -89,15 +96,13 @@ def extract_sectors(self, lap_data):
8996
if df_max is None or df_max.empty:
9097
logging.error("No valid data for sector extraction")
9198
return None, None
92-
93-
sector_start_end = self.analyzer.split_sectors(
94-
df_max, min_distance_between_sectors=35, min_length_throttle_below_threshold=20
95-
)
96-
99+
100+
sector_start_end = self.analyzer.split_sectors(df_max, min_distance_between_sectors=35, min_length_throttle_below_threshold=20)
101+
97102
if not sector_start_end or len(sector_start_end) == 0:
98103
logging.error("No sectors found during extraction")
99104
return None, None
100-
105+
101106
return sector_start_end, df_max
102107

103108
def fastest_sector(self, data_frames, start, end):

0 commit comments

Comments
 (0)