grimbough / FITfileR

R package for reading data from FIT files using only native R code, rather than relying on external libraries.
https://msmith.de/FITfileR
50 stars 13 forks source link

Power phase missing #18

Closed jpombinho closed 2 years ago

jpombinho commented 2 years ago

Hi!

I'm unable to find the following (at record): left_power_phase left_power_phase_peak right_power_phase right_power_phase_peak

The same with the corresponding averages and also the power_position (at session and lap): avg_left_power_phase avg_right_power_phase avg_left_power_phase_peak avg_right_power_phase_peak

The phases are enum'd by Start angle, End angle, Arc length and Center (start and end angle in case of the phase in the record, 4 in the case of avg): power_phase_type enum
power_phase_start_angle 0 power_phase_end_angle 1 power_phase_arc_length 2 power_phase_center 3

Also apparently missing is: avg_power_position (watts seated. watts standing) and max_power_position (watts seated, watts standing)

Can you please confirm? Any help including it is appreciated, kudos for the great work so far! :-)

Example file here: 8050504420_ACTIVITY.zip

grimbough commented 2 years ago

Thanks for the report and providing the file. Sorry it's take me so long to look at - life gets in the way of maintaining hobby projects.

It should now be possible to obtain the missing fields from your file. They'll be represented as list columns in the output tibble, Here's an example:

library(FITfileR)
library(dplyr)
library(tidyr)
library(ggforce)

## read file and extract session data
fitFile <- readFitFile("~/Downloads/8050504420_ACTIVITY.fit")
## check records
records <- records(fitFile)
names(records$record_1) %>% 
  grep(pattern = "phase", value = TRUE)
#> [1] "left_power_phase"       "left_power_phase_peak"  "right_power_phase"     
#> [4] "right_power_phase_peak"
## check session
session <- getMessagesByType(fitFile, "session")
names(session) %>%
  grep(pattern = "phase", value = TRUE)
#> [1] "avg_left_power_phase"       "avg_left_power_phase_peak" 
#> [3] "avg_right_power_phase"      "avg_right_power_phase_peak"

## these columns are lists, where each entry has 4 values
is(session$avg_left_power_phase)
#> [1] "list"   "vector"
session$avg_left_power_phase[[1]]
#> [1] 355.7813 212.3438 215.1563 104.0625

It might take a bit of work to get the values into a more useful format, but there are now there. Just for fun, here's an attempt at making the power arc plots I see in Garmin Connect:

power <- session %>%
  ## select the power phase data
  select(contains("phase")) %>%
  ## create a tibble with cols for variables, rows for observations 
  unnest(cols = everything()) %>%
  mutate(type = c("start_angle", "end_angle", "arc_length", "center")) %>%
  pivot_longer(-5) %>%
  pivot_wider(names_from = "type", values_from = "value") %>%
  ## split out the side and peak metadata
  mutate(side = if_else(grepl("left", name), "left", "right"),
         peak = if_else(grepl("peak", name), "peak", "all"),
         ## convert angles to radians
         start_angle = start_angle * (pi / 180),
         end_angle = end_angle * (pi / 180)
  ) %>%
  ## ggforce works from -pi radiens to pi radians
  mutate(start_angle = if_else(start_angle > pi, start_angle - (2*pi), start_angle))

## create arc plot for each side
colors <- c("all" = "#023047", "peak" = "#fb8500")
ggplot() +
  geom_arc(data = filter(power, peak == "all"),
           aes(x0 = 0, y0 = 0, r = 1, start = start_angle, end = end_angle, color = "all"), 
           lwd = 5) + 
  geom_arc(data = filter(power, peak == "peak"), 
           aes(x0 = 0, y0 = 0, r = 1, start = start_angle, end = end_angle, color = "peak"),
           lwd = 8) +
  facet_row(~ side) +
  coord_fixed() +
  theme_void() + 
  scale_color_manual(values = colors)

image

jpombinho commented 2 years ago

Hi Mike,

Thank you so much. Excellent work!

Best regards, João

On Mon, May 16, 2022 at 12:52 PM Mike Smith @.***> wrote:

Thanks for the report and providing the file. Sorry it's take me so long to look at - life gets in the way of maintaining hobby projects.

It should now be possible to obtain the missing fields from your file. They'll be represented as list columns in the output tibble, Here's an example:

library(FITfileR) library(dplyr) library(tidyr) library(ggforce)

read file and extract session datafitFile <- readFitFile("~/Downloads/8050504420_ACTIVITY.fit")## check recordsrecords <- records(fitFile)

names(records$record_1) %>% grep(pattern = "phase", value = TRUE)#> [1] "left_power_phase" "left_power_phase_peak" "right_power_phase" #> [4] "right_power_phase_peak"## check sessionsession <- getMessagesByType(fitFile, "session") names(session) %>% grep(pattern = "phase", value = TRUE)#> [1] "avg_left_power_phase" "avg_left_power_phase_peak" #> [3] "avg_right_power_phase" "avg_right_power_phase_peak"

these columns are lists, where each entry has 4 values

is(session$avg_left_power_phase)#> [1] "list" "vector"session$avg_left_power_phase[[1]]#> [1] 355.7813 212.3438 215.1563 104.0625

It might take a bit of work to get the values into a more useful format, but there are now there. Just for fun, here's an attempt at making the power arc plots I see in Garmin Connect:

power <- session %>%

select the power phase data

select(contains("phase")) %>%

create a tibble with cols for variables, rows for observations

unnest(cols = everything()) %>% mutate(type = c("start_angle", "end_angle", "arc_length", "center")) %>% pivot_longer(-5) %>% pivot_wider(names_from = "type", values_from = "value") %>%

split out the side and peak metadata

mutate(side = if_else(grepl("left", name), "left", "right"), peak = if_else(grepl("peak", name), "peak", "all"),

convert angles to radians

     start_angle = start_angle * (pi / 180),
     end_angle = end_angle * (pi / 180)

) %>%

ggforce works from -pi radiens to pi radians

mutate(start_angle = if_else(start_angle > pi, start_angle - (2*pi), start_angle))

create arc plot for each sidecolors <- c("all" = "#023047", "peak" = "#fb8500")

ggplot() + geom_arc(data = filter(power, peak == "all"), aes(x0 = 0, y0 = 0, r = 1, start = start_angle, end = end_angle, color = "all"), lwd = 5) + geom_arc(data = filter(power, peak == "peak"), aes(x0 = 0, y0 = 0, r = 1, start = start_angle, end = end_angle, color = "peak"), lwd = 8) + facet_row(~ side) + coord_fixed() + theme_void() + scale_color_manual(values = colors)

[image: image] https://user-images.githubusercontent.com/971237/168586354-91ba4317-2909-4dda-8096-b4a445796fc4.png

— Reply to this email directly, view it on GitHub https://github.com/grimbough/FITfileR/issues/18#issuecomment-1127574295, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGMDV62XH453UHCCESOMUYTVKIZGVANCNFSM5LS5UVTA . You are receiving this because you authored the thread.Message ID: @.***>