Fast-F1 icon indicating copy to clipboard operation
Fast-F1 copied to clipboard

[BUG] get_telemetry fails when reference lap has NaT in LapStartTime

Open markste-in opened this issue 3 years ago • 3 comments

Describe the issue:

Using fastf1 2.2.3 and python3.9

When I try to load the telemetry data for a lap where the LapStartTime is NaT the call fails.

The exact failure is in core.py in line 816 in the function calculate_driver_ahead when slice_by_data is called on the session data. There is valid session data and a reference lap but in some cases the data in the reference lap contians NaT. When slice_by_data is called it assigns NaT to start_time (line 320). Further down the line when slice_by_time is returned it compares the SessionTime to start_time what will also produce an NaT and will lead to an empty Telemetry object. That will raise an error in calculate_differential_distance.

This issue is similar to https://github.com/theOehrly/Fast-F1/issues/146

Maybe instead of throwing an error it should just spit out a warning and skip this lap / slice or don't calculate the driver ahead in this case?

Or do I do something wrong?

Reproduce the code example:

import fastf1 as ff1
ff1.Cache.enable_cache('Analysis/cache')

event = ff1.get_session(2022, 'Australia', 'Q')
event.load()
for driver_lap in event.laps.pick_driver(16).iterlaps():
    driver_tel = driver_lap[1].get_telemetry()

Error message:

Traceback (most recent call last):
  File "/opt/homebrew/Caskroom/miniforge/base/envs/f1/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 3369, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-2-6c8e21935a8d>", line 1, in <cell line: 1>
    runfile('/Users/markstein/Library/Mobile Documents/com~apple~CloudDocs/projects/f1/trouble2.py', wdir='/Users/markstein/Library/Mobile Documents/com~apple~CloudDocs/projects/f1')
  File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_umd.py", line 198, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/Users/markstein/Library/Mobile Documents/com~apple~CloudDocs/projects/f1/trouble2.py", line 8, in <module>
    driver_tel = driver_lap[1].get_telemetry()
  File "/opt/homebrew/Caskroom/miniforge/base/envs/f1/lib/python3.9/site-packages/fastf1/core.py", line 2130, in get_telemetry
    drv_ahead = car_data.iloc[1:-1].add_driver_ahead() \
  File "/opt/homebrew/Caskroom/miniforge/base/envs/f1/lib/python3.9/site-packages/fastf1/core.py", line 718, in add_driver_ahead
    drv_ahead, dist = self.calculate_driver_ahead()
  File "/opt/homebrew/Caskroom/miniforge/base/envs/f1/lib/python3.9/site-packages/fastf1/core.py", line 818, in calculate_driver_ahead
    drv_tel = drv_tel.add_distance()
  File "/opt/homebrew/Caskroom/miniforge/base/envs/f1/lib/python3.9/site-packages/fastf1/core.py", line 651, in add_distance
    new_dist = pd.DataFrame({'Distance': self.integrate_distance()})
  File "/opt/homebrew/Caskroom/miniforge/base/envs/f1/lib/python3.9/site-packages/fastf1/core.py", line 750, in integrate_distance
    ds = self.calculate_differential_distance()
  File "/opt/homebrew/Caskroom/miniforge/base/envs/f1/lib/python3.9/site-packages/fastf1/core.py", line 732, in calculate_differential_distance
    raise ValueError("Telemetry does not contain required channels 'Time' and 'Speed'.")
ValueError: Telemetry does not contain required channels 'Time' and 'Speed'.

markste-in avatar Apr 12 '22 11:04 markste-in

Yes, that is a bug. I guess skipping the problematic lap and showing a warning is the best we could do. Realistically, if this error comes up, the results might be completely wrong as there potentially is another car on track, but its position is unknown. Still, I this shouldn't just raise an error like this.

The whole .calculate_driver_ahead function is fairly problematic. I've wanted to improve it since quite some time, but I've always pushed it away because of more important things.

theOehrly avatar Apr 20 '22 22:04 theOehrly

Maybe it would be easier to make “calculate_driver_ahead“ function separate. Then it won’t impact the functionality of other functions and can still be called independently if needed

markste-in avatar Apr 21 '22 04:04 markste-in

Maybe it would be easier to make “calculate_driver_ahead“ function separate. Then it won’t impact the functionality of other functions and can still be called independently if needed

Yes, but on the other hand, if it were well written with proper error handling, this wouldn't be a problem.

I recently commented somewhere else that it maybe wasn't the best design decision to make .get_telemetry automatically add all the computed data channels. Also, plenty of people use it when it would be much better and sufficient to use .get_car_data().add_distance(). If I change how this works, then I want to do it in one go. But I'm not sure yet what the best way to proceed here is.

theOehrly avatar Apr 21 '22 12:04 theOehrly

Now fixed as a result of various improvements made to the api parser and to .calculate_driver_ahead.

theOehrly avatar Aug 26 '22 08:08 theOehrly