User Tools

Site Tools


sift:tutorials:openbiomechanics_project:thorax_movement_for_marathon_runners

Sanford Stride Project: Analysis of Vertical Thorax Oscillation, Lower-Limb Joint Kinematics and the Impact of Previous Running Experience

Abstract

Marathon running biomechanics research often examines how movement patterns influence running efficiency and performance. While lower body running mechanics have been widely studied, there has been limited research on how joint angles relate to thorax oscillations throughout the gait cycle. The Sanford Stride Project is a public markerless motion-capture dataset containing marathon runners alongside survey data including injuries, training history and running experience. This tutorial demonstrates how Visual3D and SIFT can be used to analyze vertical thorax oscillation using normalized thorax displacement alongside PCA, SPM, and K-Means clustering techniques, and if previous running experience affects thorax oscillation. We found that runners with greater thorax oscillations demonstrated notable differences in lower-limb joint angles, particularly at the ankle joint where the strongest statistical difference was observed. Similar trends were also present in the hip and knee joints. These findings suggest that joint angle patterns may be linked to vertical thorax oscillations in marathon runners and previous running experience likely has no impact.

Sample visual of one participant running through markerless motion capture with original and normalized thorax positions plotted.

Data

The following section will break down how to download the dataset, generate CMZ files using sift, and process the data using pipelines in Visual3D.

1. Dataset

This tutorial uses a public dataset by Bond, Colin.(2025). Sanford Stride Project. The original dataset can be found on thisGithub page. It includes motion tracking data captured with Theia along with self-reported survey results such as injuries, training, experience, etc.

Download the ZIP folder by selecting Code on the upper right corner of the page, then select Download Zip, you will need to extract all files.

2. Generate CMZs

Once you have downloaded the project data for this tutorial, extract the data from “\Sanford_Stride_Project_Public-main\Sanford_Stride_Project_Public-main\Sioux_Falls_Marathon_2025\Data\C3D_Files\C3D_Files.zip”.

Launch Sift, select Load Data under the Load page :

  • Click on Browse to select the C3D_Files folder that contains the data
  • Check the check box next to Build CMZs and select Merge Data

  • In the popup window of the Merge File Selections option, follow the configurations below:

Once complete, close the window and select Build CMZs. Click on Load Data to load in the data after finished building and close the window.

Now, execute the pipeline script to add the required information to the data. From the toolbar at the top of the page, click Run V3D Engine . Then click on Add Script, select the V3D_Pipelice script from the HAS_Motion folder, and click Run Scripts.

Once complete, switch to Visual3D for data processing.

3. Processing the Data in Visual3D

There are two methods that can be followed to process the data in Visual3D. You can follow the step by step instruction shown in 3.1, or use the pre-made pipeline by following the steps shown in 3.2.

  • Open Visual3D and click on the pipeline icon on the top left.

3.1. Creating pipeline from scratch

  • Create a loop using the 'For_Each' pipeline control command and clicking '»' in the workshop. Set the Iteration_Parameter_Name to 'INDEX' and use index values from 1 to 34 to loop through all the data and create the items.
For_Each
/Iteration_Parameter_Name= INDEX
/Items= 1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34
;
  • Open a file using the 'File_Open' command under File Open/Import. Change the file directory in FILENAME to match your desired location.
File_Open
/FILE_NAME=C:\Users\Clark\Downloads\intro_project\Sanford_Stride_Project_Public-main\Sanford_Stride_Project_Public-main\Sioux_Falls_Marathon_2025\Data\C3D_Files\C3D_Files\&::INDEX&\&::INDEX&.cmz
! /FILE_PATH=
! /SEARCH_SUBFOLDERS=FALSE
! /SUFFIX=
! /SET_PROMPT=File_Open
! /ON_FILE_NOT_FOUND=PROMPT
! /FILE_TYPES_ON_PROMPT=
;
  • Since we are looking to compare values between multiple participants of varying heights we need to normalize the value. Use the 'Evaluate_Expression' command with expression being LANDMARK::ORIGINAL::THORAX_ORIGIN / METRIC::PROCESSED::HEIGHT, and follow the configurations below. This needs to be done because the data is taken from people with various heights and on a decline. This step will align and categorize the data into high and low oscillation amplitudes which can be used to separate participants for the joint angles in later steps.
Evaluate_Expression
/EXPRESSION=LANDMARK::ORIGINAL::THORAX_ORIGIN / METRIC::PROCESSED::HEIGHT
/SIGNAL_TYPES=LANDMARK+METRIC 
/SIGNAL_FOLDER=PROCESSED
/SIGNAL_NAMES=THORAX_ORIGIN+HEIGHT
/SIGNAL_COMPONENTS=Z
! /RESULT_TYPES=DERIVED
! /RESULT_FOLDERS=PROCESSED
/RESULT_NAME=THORAX_NORMALIZATION_RESULT
! /APPLY_AS_SUFFIX_TO_SIGNAL_NAME=FALSE
;
  • Before the Amplitude difference can be calculated, the Maximum and Minimum values must be determined. The 'Metric_Maximum' command is used to find the maximum position of the thorax . Follow the example below to configure the pipeline.
Metric_Maximum
! /RESULT_METRIC_FOLDER=PROCESSED
/RESULT_METRIC_NAME=NORMALIZED_MAX
! /APPLY_AS_SUFFIX_TO_SIGNAL_NAME=FALSE
/SIGNAL_TYPES=DERIVED
/SIGNAL_FOLDER=PROCESSED
/SIGNAL_NAMES=THORAX_NORMALIZATION_RESULT
/COMPONENT_SEQUENCE=Z
/EVENT_SEQUENCE=LEFT_ON+RIGHT_ON
/EXCLUDE_EVENTS=
! /GENERATE_MEAN_AND_STDDEV=TRUE
! /GENERATE_MEAN_AND_STDDEV_ACROSS_SUBJECTS=FALSE
! /APPEND_TO_EXISTING_VALUES=FALSE
! /CREATE_GLOBAL_MAXIMUM=FALSE
! /CREATE_TRIAL_MAXIMUM=FALSE
;
  • To find the minimum position of the thorax the 'Metric_Minimum' command is used.
Metric_Minimum
/RESULT_METRIC_FOLDER=PROCESSED
/RESULT_METRIC_NAME=NORMALIZED_MIN
! /APPLY_AS_SUFFIX_TO_SIGNAL_NAME=FALSE
/SIGNAL_TYPES=DERIVED
/SIGNAL_FOLDER=PROCESSED
/SIGNAL_NAMES=THORAX_NORMALIZATION_RESULT
/COMPONENT_SEQUENCE=Z
/EVENT_SEQUENCE=LEFT_ON+RIGHT_ON
/EXCLUDE_EVENTS=
! /GENERATE_MEAN_AND_STDDEV=TRUE
! /GENERATE_MEAN_AND_STDDEV_ACROSS_SUBJECTS=FALSE
! /APPEND_TO_EXISTING_VALUES=FALSE
! /CREATE_GLOBAL_MINIMUM=FALSE
! /CREATE_TRIAL_MINIMUM=FALSE
;
  • The 'Evaluate_Expression' command can be used to find the difference in thorax height, follow the example below to configure the expression.
/EXPRESSION=METRIC::PROCESSED::NORMALIZED_MAX - METRIC::PROCESSED::NORMALIZED_MIN
/SIGNAL_TYPES=METRIC 
/SIGNAL_FOLDER=PROCESSED
/SIGNAL_NAMES=NORMALIZED_MAX+NORMALIZED_MIN
/SIGNAL_COMPONENTS=Z
/RESULT_TYPES=METRIC
/RESULT_FOLDERS=PROCESSED
/RESULT_NAME=THORAX_DIFF
! /APPLY_AS_SUFFIX_TO_SIGNAL_NAME=FALSE
;
  • The files must be saved, closed and loop ended. To save each file use the File_Save command with all parameters being left as default.
File_Save
! /SET_PROMPT=Save CMZ file
;
  • Now clear each workspace by creating a new file using the command 'File_New'.
File_New
;
  • Exit the loop by executing End_for_Each command with the iteration parameter being set to the same parameter as when the loop was started which for this example was 'INDEX'.
End_For_Each
/Iteration_Parameter_Name=INDEX
;
  • Now that the pipeline is complete click execute pipeline to run the commands.

3.2. Using Completed Pipeline

  • Extract process_data.zip and open the pre-made pipeline script in a text editor. Update the file directory on line 7 to match with your working directory. All other parameters can be left as default.
  • Make sure there is nothing in your pipeline, click on Open Pipeline and select process_data.v3s.

  • Click on Execute Pipeline, and it will automatically perform normalization on the Thorax_Origin landmark while also calculating the difference between the minimum and maximum value of that normalized data.
  • Once complete, you may verify the results by loading one of the files under the C3D_Files folder. Under Signals and Events, you should be able to see THORAX_NORMALIZATION_RESULT under DERIVED-PROCESSED, and THORAX_DIFF under METRIC-PROCESSED.

Define queries and calculate groups

This section will explain how to build queries and plot groups to show more relationships.

1. Reload Data

After processing data in Visual3D, return to Sift to do more analysis. As changes were made in Visual3D you must reload the data in Sift. Go back to the Load Data button on the top left and click on Load Data, you should not have to find the library path again as it should already be correct from earlier.

2. Create Queries

Once the data is loaded into sift, queries have to be made to select and group our data.

To do this, either follow the steps below and go to the explore page of sift and press Query Builder in the top left corner to build them yourself or download the premade file here.

For Thorax Difference

Step 1. Click the plus button on the top of the query builder to create a query

Step 2. Set the query name to be 'THORAX_DIFF', and press save

Step 3. Condition name can remain as condition 1 for this query

Step 4. Under the signals tab of the condition, ensure the type is METRIC, folder is PROCESSED, signal name is THORAX_DIFF and component is X

Step 5. Click Save

In order to categorize the joint angles by high and low thorax oscillation amplitudes, a group mean of the 'THORAX_DIFF' query was used. The following steps outline how to determine this value.

  • Ensure your plot type is Metric
  • Select Plot Group Mean
  • Leave all other boxes unchecked
  • Click Refresh Plot

The following graph should be generated. Click on the bar to see the mean value. This value will be used in the following query's for signal refinement. As seen below, the mean value is 0.04539.

Now all other queries must be defined. This tutorial will go through a a few definitions step by step.

Hip Angle X High Oscillation

Step 1. Click on plus button on the top of the query builder to create another query

Step 2. Name this query 'HIP_ANGLE_X_HIGH', then press save

Step 3. Name the first condition 'R_HAXH' → right hip angle x low oscillation

Step 4. Under the signal tab of the condition, ensure the type is LINK_MODEL_BASED, folder is PROCESSED, signal name is RIGHT_HIP_ANGLES and component is X

Step 5. Under the Events tab, select 'RIGHT_ON' and press the ‘>’ symbol to move it to the event sequence. Do that again for RIGHT_ON

Step 6. In the Refinement tab, click on Refine using signal, then press the Add button.

  • Name it 'HIP_ANGLE_X_HIGH'
  • Make the type 'METRIC'
  • Make the folder 'PROCESSED'
  • Make the name 'THORAX_DIFF'
  • Ensure the value must be Greater Than with a value of 0.04539 as found above
  • Press save

Step 7. Click Save

Step 8. Reflect the right side condition to create the left side condition by right clicking on the condition and pressing reflect. Ensure that all of the settings under signals reflected correctly.

Hip Angle X Low Oscillation

Step 1. Click on plus button on the top of the query builder to create another query

Step 2. Name this query 'HIP_ANGLE_X_LOW', then press save

Step 3. Name the first condition 'R_HAXL' → right hip angle x low

Step 4. Under the signal tab of the condition, ensure the type is LINK_MODEL_BASED, folder is PROCESSED, signal name is RIGHT_HIP_ANGLES and component is X

Step 5. Under the Events tab, select 'RIGHT_ON' and press the ‘>’ symbol to move it to the event sequence. Do that again for 'RIGHT_ON', as shown above

Step 6. In the Refinement tab, click on Refine using signal, then press the Add button.

  • Name it 'HIP_ANGLE_X_LOW'
  • Make the type 'METRIC'
  • Make the folder 'PROCESSED'
  • Make the name 'THORAX_DIFF'
  • Use component X
  • Ensure the value must be Less Than with a value of 0.04539 as found above
  • Press save

Step 7. Click Save

Step 8. Reflect for the left side as shown above.

These steps can be repeated for Knee and Ankle angles in the X component for high and low oscillation amplitudes as well. When doing this, make sure to use the “RIGHT_KNEE_ANGLES” for example for the signal tab.

Perform Principal Component Analysis

This section will explain how to perform PCA's on the processed data.

1. Exploring the data

To get a better observation of the groups, select Show General Options from the tool bar at the top of the page. At the bottom of the popup window, change the number of Graph Rows to 2 and number of Graph Columns to 3. This operation allows us to present all 6 groups on the same page for better comparisons.

Now, to plot the data, select a plot on the right, choose a variable to display, and click Select All Workspaces.

As you might notice, there is some abnormal data within each group. To exclude this data, select and highlight it by clicking the traces in the plot.Then right click and select Exclude → Exclude Trace. To highlight all data in all plots, simply do ctrl + H to return to the full plot.

2. Running Principal Component Analysis

Go to the Analyze tab and select the groups to include in the PCA analysis. In this example, HIP_ANGLE_X_HIGH and HIP_ANGLE_X_LOW are selected. Make sure Select All Workspaces is checked, then click Run PCA from the toolbar at the top of the page. For this example, use HIP_ANGLE as the PCA Name and set the Number of PCs to 4.

In this example, the first 4 PCs explain 95.6514% of the variation. The selected PCs should account for at least 95% of the variation; if they do not, increase the number of PCs accordingly.

Now, apply PCA to knee angle and ankle angle similarly.

Further investigation can be conducted on the PCA Analysis by looking at the different tabs at the bottom of the screen such as Workspace Scores, Group Scores, and Extreme Plot. When looking at the ANKLE_ANGLE workspace score, using PCA's 1 and 2 on the axis, you can see a clear contrast between the different groups. For other groups use the Group Scores tab to find the two PC's with the largest separation between error bars on either side of zero to use as the axis for your Workspace scores plot. This can be changed under first and second axis dropdown tabs on the top of the Workspace scores page.

Ensure that you Display Styles From Group which can be done by selecting the Show Data Options from the toolbar on the top left.

3. Run K-Means

Once PCA has been performed, use K-means testing on the results. This is an unsupervised machine learning algorithm that separates unlabeled data into clusters based on feature similarity. A more detailed K-means tutorial can be found here.

  • Select the Outlier Detection using PCA button on the top toolbar and select K-Means from the dropdown menu

  • Number of Clusters: 2
  • Maximum Iterations: 5
  • Number of PCs: NOTE: Use the number of PCs corresponding to each PCA Result. For ANKLE_ANGLE use 5 as an example.
  • Switch Display Style to by Cluster: Checked
  • Use Custom Seed for First Centroid: Checked
  • Custom Seed: 11
  • Click Run K-Means –> Once K-means clustering is completed, you will be provided with a list of summary information on each cluster like cluster center, cluster radius, and the workspaces that get grouped in each cluster.

Viewing K-Means Results

Click on Data Options and ensure that you Display Styles From Cluster.

Perform Statistical Parametric Mapping (SPM)

This section will explain how to perform SPM's on the processed data.

1. Perform Curve Registration

Before conducting the SPM, curve registration must be done because SPM works better on registered curves. This will align key events on each graph which minimizes time variance and reduces residuals, overall resulting in stronger results.

Step 1: Select a group, for this example we will use HIP_ANGLE_X_HIGH

Step 2: Select Register Curves in the bottom left corner

  • Ensure that all workspaces are selected
  • The name should automatically fill in to be HIP_ANGLE_X_HIGH_REGISTERED
  • Ensure the other conditions align as seen below. You can adjust the values for Use Local Max/Min based on the plot that you are seeing. Here, we will use an X-axis range of 35-55.

  • Click Register
  • Select and plot the result of registration. You will notice that the curves align based on the local min/max that you selected.

Step 3: Repeat for all groups

2. SPM Analysis

Step 1: Create GLMs

  • Select the two groups you want to compare by holding down CTRL on your keyboard and selecting groups, in this example we will show the comparison between ANKLE_ANGLE_X_HIGH_Registered and ANKLE_ANGLE_X_LOW_Registered
  • Select SPM from the top toolbar
    • GLM Name: GLM_ANKLE_Registered
    • Statistical Test: Two Sample T-Test
    • Group By: Group –> Ensure the groups selected are the ones selected previously
    • Use Workspace Mean: Unchecked
    • Create GLM

  • You should see two graphs, the mean signals and the corresponding Residuals

  • Repeat for all registered and unregistered curves, noting the reduced residuals from the registered curves

NOTE: You may receive the following message when computing the GLM for the unregistered curves, this is to be expected, select OK.

Step 2: Computing the SPM

  • Select Statistics in the bottom left of the SPM page
  • Select the desired GLM results on the top of the SPM page, we will use GLM_ANKLE_Registered as an example
  • Click on Compute SPM

  • SPM Name: SPM_ANKLE_Registered
  • Group 1: ANKLE_ANGLE_X_LOW_Registered
  • Group 2: ANKLE_ANGLE_X_HIGH_Registered
  • Threshold: 0.05
  • Two-Tailed: Checked
  • Click on Compute SPM

You should see the following graph showing the SPM values throughout the event cycle.

  • Repeat for all GLM Results

Results for Joint Angle Analysis

After completing the analyses for all three joints, evidence of vertical thorax oscillations affecting joint angles can clearly be observed. The relationship is most prominently seen in the ankle joint, shown by the SPM test where there is a large statistical difference between the high and low thorax oscillations groups, especially for roughly 25-50% of the event cycle. Additionally the ankle tests show a clear separation in the workspace scores after performing the PCA. Both of these graphs can be seen below.

When analyzing the Hip and Knee angles similar trends can be seen in the SPM analysis with different portions of the event cycle showing clear statistical differences for both. However, neither showed the same degree of separation in the workspace scores as the ankle joint.

PCA Workspace Score Results for Hip, Knee, and Ankle

SPM Results for Registered Hip, Knee, and Ankle

Explore Relationships Between Previous Experiences and Vertical Thorax Oscillations

The following section will use PCA and SPM analysis to determine if the self reported previous running experience impacts thorax oscillations.

Perform Tagging Based on Experience Levels

To study whether runners’ previous experience affects thorax oscillation amplitudes, we will begin by categorizing runners based on their prior experience.

According to the Data Dictionary, there are a total of 7 levels:

  • 0: I have not been running regularly
  • 1: Less than a year
  • 2: 1-3 years
  • 3: 4-6 years
  • 4: 7-10 years
  • 5: 11-15 years
  • 6: More than 15 years

As no runners were labeled with an experience level of 0, this category will not be considered in the study.

1. Create Pipeline Script

A pipeline script was created to automize the process of adding tags, and can be done by executing the script in tag_expereinces.zip from a clean workspace after updating the directory to the CMZ files. The details of the script is explained below:

  • The pipeline script begins with a configuration of the directory to the CMZ files:
Set_Pipeline_Parameter 
/PARAMETER_NAME=CMZ_DIR
/PARAMETER_VALUE=C:\Users\Clark\Downloads\intro_project\Sanford_Stride_Project_Public-main\Sanford_Stride_Project_Public-main\Sioux_Falls_Marathon_2025\Data\C3D_Files\C3D_Files\
;
  • A loop was created to iterate through the files that needs to be tagged, in following example, data of runners with level 1 experiences are being processed.
For_Each
/Iteration_Parameter_Name= INDEX
/Items= 4+11+18
;
  • Open one file at a time and tag is assigned to the opened file.
File_Open
/FILE_NAME=::CMZ_DIR&::INDEX&\&::INDEX&.cmz
! /FILE_PATH=
! /SEARCH_SUBFOLDERS=FALSE
! /SUFFIX=
! /SET_PROMPT=File_Open
! /ON_FILE_NOT_FOUND=PROMPT
! /FILE_TYPES_ON_PROMPT=
;
Assign_Tags_To_Files
/MOTION_FILE_NAMES=ALL_FILES
! /QUERY=
/TAGS=Experience_LV1
;
  • Before moving on to open the next file, we want to save the changes and clear the workspace.
File_Save
! /SET_PROMPT=Save CMZ file
;
! Clear workspace
File_New
;
  • Eventually, we need to create the end point for the loop.
End_For_Each
/Iteration_Parameter_Name=INDEX
;
  • Now that tags have been assigned to all runners with experience level 1, the same process can be repeated to assign tags to the remaining runners.

Define queries and calculate groups

This section will explain how to build queries using the processed data.

1. Define Queries

To examine the relationship between runners’ experience levels and thorax oscillation, the six experience levels are divided into two categories:

  • Upper three experience levels (4-6)
  • Lower three experience levels (1-3)

The queries can be imported by selecting the extracted file of queries_with_experiences.zip in the Load Query Definitions option within the Query Builder. However, an example demonstrating how to build these four queries is provided below.

2. Build Queries

The process begins with the UPPER_3_EXPERIENCE query.

For this query, make following configurations under Signals Tab:

  • Set the Query Name to UPPER_3_EXPERIENCE
  • Configure the Type to DERIVED
  • Configure the Folder to PROCESSED
  • The signal to be analyzed to THORAX_NORMALIZATION_RESULT
  • Configure the Component to Z

Under Events, set the Event Sequence to RIGHT_ON and RIGHT_ON.

And finally:

  • Select Refine using tag under Refinement and highlight LV4-LV6

The query for level 1-3 can be completed similarly with the necessary adjustments made accordingly.

After completing the queries, register the curves to align the curves better. Instructions for this can be found above. The results of the curve registration are presented below.

Perform Principal Component Analysis

To understand whether runners’ experience levels affect vertical thorax oscillation, we will compare thorax movement for runners across different levels of running experience. More detailed instructions on running a PCA can be found above.

1. Running Principal Component Analysis

  1. Ensure that groups and workspaces that needs to be performed PCA on are selected in the Groups and Workspaces list. For our case, select UPPER_3_EXPERIENCE and LOWER_3_EXPERIENCE.
  2. Select Run PCA from the toolbar at the top of the page.
  3. Configure the name for this PCA, and set the Number PCs to 4.
  4. Ensure that User Workspace Mean is checked and click Run PCA.

The PCA workspace score graph for the high oscillation amplitudes group can be seen below. Further analysis of the PCA statistics can be found under the Results section.

Perform Statistical Parametric Mapping

Similar to PCA, follow the SPM steps outlined above. Ensuring that you register all the curves before computing the GLM and then SPM. Remember to compare the two high groups and the two low groups. After computing the GLM you should see the mean signals and corresponding residual plots that resemble the ones shown below for the high and low registered groups.

After computing the GLM you can now compute the SPM, your SPM pop up page should resemble the following.

Results for Previous Experience Analysis

Based on both the PCA and SPM analysis it was evident that there is little correlation between previous running experience and a thorax with low oscillation amplitudes. With the only slight correlation being seen in the first 30% of the gait cycle for runners with low thorax oscillation amplitudes. This shows that more experienced marathon runners may not consider thorax movement in their training.

PCA Results

PCA on Low Oscillation Amplitude Groups

Although four principal components explain 99.83% of the variation, most of the variation is explained by the first principal component, meaning that the data is highly correlated. On the Group Scores page, the mean scores for nearly all principal components cross the x-axis, indicating that the groups are not clearly differentiated in the PCA space.

SPM Results

The SPM result shown below is specifying that there might not be a strong relationship between running experiences and thorax oscillation amplitude, but further study needs to be performed in order to be certain, as there are too few data in the data set that was used for this research.

Conclusion

In conclusion, there is evidence of a possible relationship between vertical thorax oscillations and lower body joint angles in marathon runners. However, no evidence was found showing a link between previous running experience and oscillation amplitude. This suggests that marathon runners may not prioritize maintaining low movement in the thorax during training and therefore incorporating thorax strengthening exercises into training programs could improve overall running mechanics and control. This may include strengthening the runner’s core muscles, which play an important role in maintaining torso control. Examples of such exercises include planks, glute bridges, and hollow holds. nike. Overall, evidence suggests a relationship between vertical thorax oscillations and lower limb joint angles, while thorax oscillation and previous experience were found to be independent.

sift/tutorials/openbiomechanics_project/thorax_movement_for_marathon_runners.txt · Last modified: by wikisysop