Skip to content

Commit

Permalink
Merge pull request #220 from pbulsink/old_ff1_deprecating
Browse files Browse the repository at this point in the history
Deprecating support of FastF1 < 3.1.0
  • Loading branch information
SCasanova authored Jan 29, 2024
2 parents fbd1213 + 8833bc9 commit 9ca668a
Show file tree
Hide file tree
Showing 23 changed files with 295 additions and 134 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/check-standard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ jobs:

runs-on: ${{ matrix.config.os }}

name: ${{ matrix.config.os }} (${{ matrix.config.r }})
name: HARD ${{ matrix.config.os }} (${{ matrix.config.r }})

strategy:
fail-fast: false
Expand Down
63 changes: 63 additions & 0 deletions .github/workflows/test-coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,69 @@ jobs:
name: coverage-test-failures
path: ${{ runner.temp }}/package

test-coverage-hard:
# NOTE: This workflow only directly installs "hard" dependencies, i.e. Depends,
# Imports, and LinkingTo dependencies. Notably, Suggests dependencies are never
# installed, with the exception of testthat, knitr, and rmarkdown. The cache is
# never used to avoid accidentally restoring a cache containing a suggested
# dependency.

runs-on: ubuntu-latest

name: Test coverage - HARD

strategy:
fail-fast: false

env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
R_KEEP_PKG_SOURCE: yes

steps:
- uses: actions/checkout@v3

- uses: r-lib/actions/setup-pandoc@v2

- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true

- uses: r-lib/actions/setup-r-dependencies@v2
with:
dependencies: '"hard"'
cache: false
extra-packages: |
any::rcmdcheck
any::testthat
any::knitr
any::rmarkdown
any::markdown
any::covr
needs: coverage

- name: Test coverage
run: |
covr::codecov(
quiet = FALSE,
clean = FALSE,
install_path = file.path(Sys.getenv("RUNNER_TEMP"), "package")
)
shell: Rscript {0}

- name: Show testthat output
if: always()
run: |
## --------------------------------------------------------------------
find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true
shell: bash

- name: Upload test results
if: failure()
uses: actions/upload-artifact@v3
with:
name: coverage-test-failures
path: ${{ runner.temp }}/package

test-pkgdown-ok:
name: Test pkgdown ok
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ f1dataR.Rproj
/doc/
/Meta/
/tst_*
Rplots.pdf
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# f1dataR (development version)

* Deprecated support for FastF1 v < 3.1.0. Older FastF1 versions do not support all of the functions in use and may return different values from some data retrieval or calculation functions. Forcing use of up-to-date FastF1 allows for simpler bugfixes and code updates. (#198)
* Code cleanup (removed old inaccessible code, centralized repeated steps to functions, etc.)

# f1dataR 1.5.0

* Added `load_circuit_details` (#210)
Expand Down
18 changes: 4 additions & 14 deletions R/circuit_details.R
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,12 @@
#'
#' @export
load_circuit_details <- function(season = get_current_season(), round = 1, log_level = "WARNING") {
if (get_fastf1_version()$major < 3 || (get_fastf1_version()$major == 3 && get_fastf1_version()$minor < 1)) {
cli::cli_abort("An old version of FastF1 is in use. FastF1 verison 3.1.0 or later.")
}
# Deprecation Checks
check_ff1_version()

# Function Code
load_race_session(obj_name = "session", season = season, round = round, session = "R", log_level = log_level)

tryCatch(
{
# Only returns a value if session.load() has been successful
# If it hasn't, retry
reticulate::py_run_string("session.t0_date")
},
error = function(e) {
reticulate::py_run_string("session.load()")
}
)
check_ff1_session_loaded(session_name = "session")

py_env <- reticulate::py_run_string("circuit_info = session.get_circuit_info()")

Expand Down
19 changes: 6 additions & 13 deletions R/clear_f1_cache.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,12 @@ clear_f1_cache <- function() {
if (reticulate::py_available(initialize = TRUE)) {
if ("fastf1" %in% reticulate::py_list_packages()$package) {
reticulate::py_run_string("import fastf1")
if (get_fastf1_version()$major >= 3) {
try(
reticulate::py_run_string(glue::glue("fastf1.Cache.clear_cache('{cache_dir}')",
cache_dir = normalizePath(getOption("f1dataR.cache"))
))
)
} else {
try(
reticulate::py_run_string(glue::glue("fastf1.api.Cache.clear_cache('{cache_dir}')",
cache_dir = normalizePath(getOption("f1dataR.cache"))
))
)
}

try(
reticulate::py_run_string(glue::glue("fastf1.Cache.clear_cache('{cache_dir}')",
cache_dir = normalizePath(getOption("f1dataR.cache"))
))
)
}
}

Expand Down
56 changes: 10 additions & 46 deletions R/load_driver_telemetry.R
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,19 @@
load_driver_telemetry <- function(season = get_current_season(), round = 1, session = "R", driver, laps = "fastest",
log_level = "WARNING", race = lifecycle::deprecated(),
fastest_only = lifecycle::deprecated()) {
# Lifecycles
# Deprecation Checks
if (lifecycle::is_present(race)) {
lifecycle::deprecate_stop("1.4.0", "load_driver_telemetry(race)", "load_driver_telemetry(round)")
round <- race
}
if (lifecycle::is_present(fastest_only)) {
lifecycle::deprecate_stop("1.4.0", "load_driver_telemetry(fastest_only)", "load_driver_telemetry(laps)")
if (fastest_only) {
laps <- "fastest"
} else {
laps <- "all"
}
}
check_ff1_version()

# Function Code
# Param checks
if (!(laps %in% c("fastest", "all"))) {
if (is.numeric(laps)) {
if (get_fastf1_version()$major < 3) {
cli::cli_abort("{.var laps} can only be a lap number if using fastf1 v3.0 or higher")
}
if (as.numeric(laps) != as.integer(laps)) {
cli::cli_abort("{.var laps} must be one of `fastest`, `all` or an integer value")
}
Expand All @@ -68,35 +61,19 @@ load_driver_telemetry <- function(season = get_current_season(), round = 1, sess
}

load_race_session(obj_name = "session", season = season, round = round, session = session, log_level = log_level)

tryCatch(
{
# Only returns a value if session.load() has been successful
# If it hasn't, retry
reticulate::py_run_string("session.t0_date")
},
error = function(e) {
reticulate::py_run_string("session.load()")
}
)

if (get_fastf1_version()$major < 3) {
add_v3_option <- ""
} else {
add_v3_option <- ".add_driver_ahead()"
}
check_ff1_session_loaded(session_name = "session")

if (laps == "fastest") {
reticulate::py_run_string(glue::glue("tel = session.laps.pick_driver('{driver}').pick_fastest().get_telemetry().add_distance(){opt}",
driver = driver, opt = add_v3_option
reticulate::py_run_string(glue::glue("tel = session.laps.pick_driver('{driver}').pick_fastest().get_telemetry().add_distance().add_driver_ahead()",
driver = driver
))
} else if (laps != "all") {
reticulate::py_run_string(glue::glue("tel = session.laps.pick_driver('{driver}').pick_lap({laps}).get_telemetry().add_distance(){opt}",
driver = driver, laps = laps, opt = add_v3_option
reticulate::py_run_string(glue::glue("tel = session.laps.pick_driver('{driver}').pick_lap({laps}).get_telemetry().add_distance().add_driver_ahead()",
driver = driver, laps = laps
))
} else {
reticulate::py_run_string(glue::glue("tel = session.laps.pick_driver('{driver}').get_telemetry().add_distance(){opt}",
driver = driver, opt = add_v3_option
reticulate::py_run_string(glue::glue("tel = session.laps.pick_driver('{driver}').get_telemetry().add_distance().add_driver_ahead()",
driver = driver
))
}
py_env <- reticulate::py_run_string(paste("tel.SessionTime = tel.SessionTime.dt.total_seconds()",
Expand Down Expand Up @@ -135,17 +112,4 @@ get_driver_telemetry <-
"get_driver_telemetry()",
"load_driver_telemetry()"
)

# default fastest only to TRUE
fastest_only <- ifelse(lifecycle::is_present(fastest_only), fastest_only, TRUE)

load_driver_telemetry(
season = season,
round = round,
session = session,
driver = driver,
laps = ifelse(fastest_only, "fastest", "all"),
log_level = log_level,
race = race
)
}
5 changes: 4 additions & 1 deletion R/load_laps.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@
#' @return A tibble with columns driver_id (unique and recurring), position
#' during lap, time (in clock form), lap number, time (in seconds), and season.
load_laps <- function(season = get_current_season(), round = "last", race = lifecycle::deprecated()) {
# Deprecation Check
if (lifecycle::is_present(race)) {
lifecycle::deprecate_stop("1.4.0", "load_laps(race)", "load_laps(round)")
round <- race
}

# Parameter Check
if (season != "current" && (season < 1996 || season > get_current_season())) {
cli::cli_abort('{.var season} must be between 1996 and {get_current_season()} (or use "current")')
}

# Function Code
url <- glue::glue("{season}/{round}/laps.json?limit=1000",
season = season, round = round
)
Expand Down
5 changes: 4 additions & 1 deletion R/load_pitstops.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@
#' @return A tibble with columns driver_id, lap, stop (number), time (of day),
#' and stop duration
load_pitstops <- function(season = get_current_season(), round = "last", race = lifecycle::deprecated()) {
# Deprecation check
if (lifecycle::is_present(race)) {
lifecycle::deprecate_stop("1.4.0", "load_pitstops(race)", "load_pitstops(round)")
round <- race
}

# Parameter Check
if (season != "current" && (season < 2011 || season > get_current_season())) {
cli::cli_abort('{.var season} must be between 2011 and {get_current_season()} (or use "current")')
}

# Function Code
url <- glue::glue("{season}/{round}/pitstops.json?limit=80",
season = season, round = round
)
Expand Down
21 changes: 6 additions & 15 deletions R/load_race_session.R
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@
#' }
load_race_session <- function(obj_name = "session", season = get_current_season(), round = 1, session = "R",
log_level = "WARNING", race = lifecycle::deprecated()) {
# Deprecation Checks
if (lifecycle::is_present(race)) {
lifecycle::deprecate_stop("1.4.0", "load_race_session(race)", "load_race_session(round)")
round <- race
}
check_ff1_version()

# Function Code
if (season != "current" && (season < 2018 || season > get_current_season())) {
cli::cli_abort('{.var season} must be between 2018 and {get_current_season()} (or use "current")')
# stop(glue::glue('Year must be between 2018 and {current} (or use "current")',
Expand Down Expand Up @@ -69,10 +72,7 @@ load_race_session <- function(obj_name = "session", season = get_current_season(
}

reticulate::py_run_string("import fastf1")
if (get_fastf1_version()$major >= 3) {
reticulate::py_run_string(glue::glue("fastf1.set_log_level('{log_level}')", log_level = log_level))
}

reticulate::py_run_string(glue::glue("fastf1.set_log_level('{log_level}')", log_level = log_level))
reticulate::py_run_string(glue::glue("fastf1.Cache.enable_cache('{cache_dir}')", cache_dir = f1datar_cache))

py_string <- glue::glue("{name} = fastf1.get_session({season}, ", name = obj_name, season = season)
Expand All @@ -91,16 +91,7 @@ load_race_session <- function(obj_name = "session", season = get_current_season(

session <- reticulate::py_run_string(glue::glue("{name}.load()", name = obj_name))

tryCatch(
{
# Only returns a value if session.load() has been successful
# If it hasn't, retry
reticulate::py_run_string("session.t0_date")
},
error = function(e) {
reticulate::py_run_string(glue::glue("{name}.load()", name = obj_name))
}
)
check_ff1_session_loaded(session_name = obj_name)

invisible(session[obj_name])
}
24 changes: 6 additions & 18 deletions R/load_session_laps.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,15 @@
#'
load_session_laps <- function(season = get_current_season(), round = 1, session = "R", log_level = "WARNING",
add_weather = FALSE, race = lifecycle::deprecated()) {
# Deprecation Checks
if (lifecycle::is_present(race)) {
lifecycle::deprecate_stop("1.4.0", "load_session_laps(race)", "load_session_laps(round)")
round <- race
}

if (get_fastf1_version()$major < 3) {
cli::cli_alert_warning("An old version of FastF1 is in use. Additional data is provided if using FastF1 v3.0.0 or later.")
}
check_ff1_version()

# Function Code
load_race_session(obj_name = "session", season = season, round = round, session = session, log_level = log_level)

tryCatch(
{
# Only returns a value if session.load() has been successful
# If it hasn't, retry
reticulate::py_run_string("session.t0_date")
},
error = function(e) {
reticulate::py_run_string("session.load()")
}
)
check_ff1_session_loaded(session_name = "session")

reticulate::py_run_string("laps = session.laps")
if (add_weather) {
Expand All @@ -60,7 +48,7 @@ load_session_laps <- function(season = get_current_season(), round = 1, session
))
}

if (session == "Q" && get_fastf1_version()$major >= 3) {
if (session == "Q") {
# prepping for Q1/Q2/Q3 labels - this has to happen before timedelta64 is converted to seconds
reticulate::py_run_string(paste("q1, q2, q3 = session.laps.split_qualifying_sessions()",
"q1len = len(q1.index)",
Expand Down Expand Up @@ -91,7 +79,7 @@ load_session_laps <- function(season = get_current_season(), round = 1, session
laps <- laps %>%
dplyr::mutate("Time" = .data$Time)

if (session == "Q" && get_fastf1_version()$major >= 3) {
if (session == "Q") {
# pull the lengths of each Quali session from the python env.
q1len <- reticulate::py_to_r(reticulate::py_get_item(py_env, "q1len"))
q2len <- reticulate::py_to_r(reticulate::py_get_item(py_env, "q2len"))
Expand Down
Loading

0 comments on commit 9ca668a

Please sign in to comment.