Accessing 10 Hz Data

How to access 10 Hz Data.

Table of Contents


Introduction

10 Hz data can also be accessed for a specified athlete and activity. No specific events or efforts are provided with this data, but it can be useful if you are interested in analyzing continuous tracking data over various time intervals.

Performance

Due to the larger file size associated with 10 Hz data, the time required for download is substantially longer. There are also significant demands on memory during download. It is recommended that these types of API requests be completed in small batches on a machine with adequate memory.

10 Hz data can also be accessed through OpenField console on an Activity-by-Activity basis. Data is exported in a CSV format per individual athlete contained within the activity. These files can then be read into R using read.csv().

Validate User Credentials

If enabled on your account, you can also generate an API token string in OpenField Cloud. If you would like this feature enabled on your OpenField account, please speak with your Catapult Sports Customer Success Representative.

For this example, we will extract all Rugby Union IMA events from a game in our Men’s Rugby Union demo account. First we have to get the token corresponding to this account.

All data presented along with account credentials have been anonymized, removing and changing identifiable characteristics that can be traced back to an account, team, or athlete. Typical token strings created in OpenField Cloud will be much longer.


# first, load a few packages
library(catapultR)
library(tidyverse)
library(lubridate)

token <- ofCloudCreateToken(sToken = "8SyAJZonGYUH5adDgINl1re7WkOPXhB0EtbVzcMp",  sRegion = "America")

Getting Athletes and Activities

Now, we can see which athletes and activities are associated with this account. Typically, you will want to identify specific athletes or activities for which you want more information. Once you know when these Activities occurred and the Device IDs that you’re interested in, you can access IMA Event data, Generation 2 Effort data, 10 Hz Sensor Data, or even 100 Hz high frequency data if the necessary modules are enabled on the account.

In order to maintain anonymity, no identifiable data will be shared for the following examples.

Athletes:


athletes <- ofCloudGetAthletes(token)
# glimpse(athletes)
glimpse(athletes)

Rows: 280
Columns: 29
$ id                         <fct> 7pkjvzc2-pf7x-si7l-jldg-axb2lf7vw~
$ first_name                 <chr> "Annnees", "Brian", "Anthony", "B~
$ last_name                  <chr> "Engelhart", "Simion", "Weiss", "~
$ jersey                     <chr> "123", "DM5", "JC", "EO1", "WS5",~
$ nickname                   <chr> "", "", "Mailman", "Sleepy", "", ~
$ height                     <dbl> 178.002063161, 182.702953896, 181~
$ weight                     <dbl> 64.5848746855, 66.0066343451, 74.~
$ date_of_birth              <dbl> 769560828, 785147237, 802150884, ~
$ velocity_max               <dbl> 10.00, 10.00, 9.00, 9.50, 8.20, 8~
$ acceleration_max           <int> 0, 0, 0, 0, 0, 0, 0, 10, 10, 0, 1~
$ heart_rate_max             <int> 0, 0, 200, 196, 199, 0, 200, 193,~
$ player_load_max            <int> 0, 0, 500, 0, 0, 0, 0, 10, 10, 50~
$ image                      <chr> "", "", "", "", "", "", "", "6695~
$ icon                       <chr> "circle", "circle", "circle", "tr~
$ stroke_colour              <chr> "#030303", "#030303", "#030303", ~
$ fill_colour                <chr> "#ff0000", "#ff0000", "#ff0000", ~
$ trail_colour_start         <chr> "", "", "", "", "", "", "", "#000~
$ trail_colour_end           <chr> "", "", "", "", "", "", "", "#000~
$ is_synced                  <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
$ is_deleted                 <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
$ created_at                 <chr> "2015-06-22 10:04:02", "2015-07-0~
$ modified_at                <chr> "2015-07-31 08:38:44", "2016-09-1~
$ tag_list                   <list> [], [], [], [], [], [], [], [], ~
$ tags                       <list> [], [], [], [], [], [], [], [], ~
$ current_team_id            <chr> "9xvyke5n-hgrc-r7v6-8dtj-31bhkszm~
$ max_player_load_per_minute <int> 12, 12, 15, 15, 15, 12, 12, 15, 1~
$ position                   <chr> "SH", "S", "C", "FB", "S", "FL", ~
$ position_id                <chr> "b93eae54-7071-11e4-afbc-0afe0c90~
$ position_name              <chr> "Scrum-Half", "Second Row", "Cent~


Activities:


# Get data for each activity (Demo Account) ----------------------------------------------
to <- as.integer(as.POSIXct(as.Date("2020-02-02")))
from <- as.integer(as.POSIXct(as.Date("2019-10-02"))) # 20 weeks
activities <- ofCloudGetActivities(token, from = from, to = to)
glimpse(activities)
nrow(activities)

Rows: 180
Columns: 19
$ id             <chr> "pkjv7c2u-pf7x-si7l-jldg-axb2lf7vw9c8", "pdvz~
$ name           <chr> "Rehab", "Training", "Training", "Rehab", "Ma~
$ start_time     <dbl> 1584697281, 1584611296, 1584522199, 158447928~
$ end_time       <dbl> 1584699565, 1584612900, 1584524248, 158448302~
$ modified_at    <chr> "2020-01-31 17:15:48", "2020-01-31 17:15:48",~
$ game_id        <chr> "pkjv7c2u-pf7x-si7l-jldg-axb2lf7vw9c8", "pdvz~
$ owner_id       <chr> "efcb4474-22a6-41fc-95ce-8389d6e8fd36", "efcb~
$ owner          <df[,10]> <data.frame[23 x 10]>
$ periods        <list> [<data.frame[1 x 4]>], [<data.frame[1 x 4~
$ tags           <list> <"Friday", "Compressed", "GPS", "Compressed"~
$ tag_list       <list> [<data.frame[4 x 5]>], [<data.frame[2 x 5]>]~
$ athlete_count  <int> 1, 1, 1, 1, 1, 1, 27, 1, 2, 2, 7, 34, 1, 2, ~
$ period_count   <int> 1, 1, 1, 1, 1, 1, 46, 1, 2, 1, 6, 7, 1, 1, 1,~
$ venue_name     <chr> "Training Pitch 2", "Training Pitch 3", "Trai~
$ venue_width    <int> 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 7~
$ venue_length   <int> 105, 105, 105, 105, 105, 105, 105, 105, 105, ~
$ venue_rotation <int> 169, 169, 169, 169, 169, 169, 169, 169, 169, ~
$ venue_lat      <dbl> 71.7755572, 71.7755572, 71.7755572, 71.775557~
$ venue_lng      <dbl> -19.3345743, -19.3345743, -19.3345743, -19.33~

[1] 180


We can use the activities data frame above to identify an activity or period from which we would like to extract the velocity or acceleration efforts We also need the athlete_id for each athlete, and the corresponding name of each athlete will also be helpful. For this example, I will just select a random activity. To get the athlete_ids and athlete_names for this activity, we can use the function ofCloudGetAthleteDevices().

Get Device Info for the Activity


# We want athlete name, athlete_id, and device_id
# we can match the name using the device id from the info returned by ofCloudGetAthleteDevices()
device_info <- ofCloudGetAthleteDevicesInActivity(
  token, 
  activity_id = activities$id[27])

glimpse(device_info)

Rows: 32
Columns: 12
$ device_id          <int> 3904, 1083, 8903, 8558, 7337, 9171, 6702,~
$ athlete_id         <chr> "dnc3ystx-mvfe-d2ey-cx14-25i14qtmaglo", "~
$ athlete_name       <chr> "Dao Ibarra", "Dillon Lovato", "Cindy Kea~
$ athlete_first_name <chr> "Dao", "Dillon", "Cindy", "Joshua", "Ange~
$ athlete_last_name  <chr> "Ibarra", "Lovato", "Keasling", "Tree", "~
$ mapping_start_time <dbl> 1581406289, 1581406180, 1578641056, 15829~
$ mapping_end_time   <dbl> 1583481593, 1641898572, 1583416017, 15832~
$ is_current_mapping <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,~
$ jersey             <chr> "CH5", "AC8", "KP2", "DT2", "SM4", "TL3",~
$ team_id            <chr> "iuctbanw-twg7-rqwc-ijzc-icbfwuv5z89p", "~
$ team_name          <chr> "Ravenclaw", "Ravenclaw", "Ravenclaw", "R~
$ player_id          <chr> "", "", "", "", "", "", "", "", "", "", "~

The column names for device_info have been printed above. The device_id column can be used to join athlete names to the event data.


Extracting and Analyzing 10 Hz Data

To get 10 Hz “Sensor Data” for a single athlete, the function ofCloudGetActivitySensorData() can be used. You must specify an athlete_id and activity_id for the 10 Hz data. You can use the function ofCloudGetAthleteDevicesInActivity() to get a dataframe of relevant athlete_id’s for each activity. We did this above to create the device_info dataframe.


Accessing 10 Hz data for a Single Athlete

We can access the 10 Hz data for a specified device_id.


# get 10hz for a single athlete
sd <- ofCloudGetActivitySensorData(
     token, 
     athlete_id = device_info$athlete_id[1], 
     activity_id = activities$id[27])

glimpse(sd)

# look at middle of file
sd %>% 
  unnest(cols = "data") %>% 
  slice(2000:2100) %>% 
  rmarkdown::paged_table() 

Rows: 1
Columns: 11
$ athlete_id         <chr> "7a62b7e1-401f-4282-b309-04ae3e459db3"
$ device_id          <int> 9920
$ player_id          <chr> ""
$ athlete_first_name <chr> "Maurice"
$ athlete_last_name  <chr> "Hughes"
$ jersey             <chr> "CH5"
$ team_id            <chr> "75054b55-9900-11e3-b9b6-22000af8166b"
$ team_name          <chr> "Werewolves"
$ stream_type        <chr> "gps"
$ data               <list> [<data.frame[7079 x 13]>]
$ activity_id        <chr> "7pkjvzc2-pf7x-si7l-jldg-axb2lf7vw9c8"

Definition of the 10 Hz parameters

Conclusion

You have now accessed 10 Hz data for a single athlete. You can extend the logic for multiple athletes and multiple activities if you wish. For other types of data requests, proceed to another section of the Quick Start Tutorial.

Contact: (email) | #ask_catapultR (Slack)