I like watches and the Garmin Forerunner caught my eye. So to justify buying one I’ve had to start running!
OK I’m not fit. But that’s the point.
My problem is that I used to run, and I have a vague memory of my competitive pace but clearly my body is no longer able to perform at that level. Instead of trying to do a 5k race in 18 minutes I have to accept that 30 minutes is probably a more realistic goal. And even for that I have to get into shape. The Garmin watch is great because it allows me to target a heart rate training zone rather than measuring performance purely in terms of distance and pace.
I can also upload data from the watch to the Garmin Connect website to view various graphs and performance stats. That’s great, but I want to do some custom analysis. In particular, I notice that I can run only for a limited period of time before my heart rate exceeds my training zone. I would like to monitor the rate at which my heart rate increases to see if it is a useful measure of fitness.
I know using JMP I could do this. So how do I get the data into JMP?
I can export data in TCX format. This is an XML format. Opening the file in a browser I see it has the following structure:
Each lap has the following structure:
The raw data from the watch is contained in the Track element:
Of course to make use of this data I need to get it into JMP. Fortunately JMP can handle XML data. But I’ve not done it before so for your benefit and mine I’m going to outline process step by step.
My start point is that I have downloaded the TCX file from the Garmin Connect website; it is called activity_871487392.tcx.
XML is formatted text, and I can load the text into a string variable:
filename = "activity_871487392.tcx"; content = Load Text File(filename);
To decompose the content into usable data JMP can perform a task known as XML Parsing. JMP scans the content and raises events based on its structure. For example JMP will raise events each time it sees an opening tag (e.g. <Lap ….) or a closing tag ( …./Lap>) for the element “lap”. My job is to write JSL code that will react to these events.
I want to place the contents of an activity into a JMP table so when JMP detects the start of an activity I want to create a new table:
filename = "activity_871487392.tcx"; content = Load Text File(filename); ParseXML(content, On Element( "Activity", Start Tag( New Table( "new activity" ); ) ) );
Before I try and drill down to the detailed track data I will test to make sure I can read the lap data into this table.
I can add an additonal “On Element” event hander to deal with data elements contained with each lap. To illustrate this I’ll focus on maximum heart rate.
On Element( "MaximumHeartRateBpm", End Tag( data = Parse( XML Text() ); InsertInto(lstMaxBpm, data) ), ),
If for example the file contains:
then data will contain the number 137 (the XML Text function retrieves the value 137 as a text string; the Parse function ensures I retrieve numeric values as numbers and not text.
I’m putting all of the data values into a list. I need to initialise this list at the same time I created the new table, and at the end of the Activity element I want to use this list to create a new data column.
Here is the full code:
Which produces the following table:
I’ve confirmed that I can read and process the data in the TCX file produced from the Garmin Connect website. Now I can work on selecting the more detailed information that I want to track my performance. Maybe that will be another blog entry or an addin!