User Tools

Site Tools


sift:tutorials:openbiomechanics_project:impact_shooting_arm_mechanics_free_throw_accuracy

Impact of Shooting Arm Mechanics on Free Throw Accuracy Using PCA, K-Means, and SPM

Abstract

Free throws are an integral part of the game of basketball, with many games being decided by a team’s success at the line (or lack thereof). While extensive research on free throw biomechanics has been done, there is limited research available on the direct link between shooting arm mechanics and shot results [1]. The literature often compares discrete metrics to assess inter-variability between players, as opposed to intra-variability over an entire waveform. This tutorial will show how this could be applied using a case study of N=1. Here we use SPM, PCA, and K-means in SIFT to analyze MLSE’s free throw data set and identify a link between shooting arm movement patterns and shooting accuracy. We found that variance in a shooter’s wrist, shoulder, and elbow flexion, particularly at maximum elbow flexion and during the ball’s release were most closely linked to larger left and right misses. Based on these findings we conclude that consistency in a shooter’s shoulder and wrist flexion, in synchrony with their elbow extension are key factors in improving shooting accuracy.

Data

This tutorial will uses a public dataset made available by MLSE. The data set includes 125 trials of one non-professional athlete completing free throws over the course of 2-3 hours. The data was collected by MLSE's Sport Performance Lab using markerless motion capture. This dataset was made available to the public with the goal to inspire the future release of more biomechanical data from other organizations to drive further advancement in the field. The dataset is available through the Sport Performance Lab's Github repository.

In the repository, navigate to basketball/freethrow and download the data/P001 folder which contains the dataset.


The trials in the dataset are organized as JSON files (“BB_FT_P0001_T000X.json”), where x refers to the trial ID. Each ID represents one free-throw that took place within the single session by one participant. The pose keypoints and the ball are shown in xyz positions measured in feet (in accordance with measurements in the NBA handbook). Within the README.md file there is an in-depth explanation of the court coordinate system seen below and the 27 pose marker positions used.

Image from MLSE Sport Performance Lab and used under permission. The motion capture dataset's coordinate system is shown relative to an NBA-regulation basketball court. The z-axis points “up”, out of the screen.

The XYZ Cardan Sequence coordinate system was used to capture the complexity of the free throw motion. Using this sequence aids in not only seeing the joint angles change throughout the free throw motion but the ball trajectory as well. An in-depth explanation about the Cardan Sequence is given in Lees, Barton, and Robinson's article [2].

Both the dataset and the reproduced figures above are used with permission from the MLSE Sport Performance Lab.

Visual3D for Data Processing

Follow the steps below to build and execute the pipelines needed to process the raw dataset. Each pipeline will be organized by function, and separated into four .v3s scripts. Alternatively, the completed pipelines can be downloaded here: Completed Pipeline. The pipeline serves to automate specific processing commands like sorting and event marking across all files in the dataset.

Folder structure

First, create a root folder 'FreeThrowProject'. Within it, create a folder 'V3dPipelines' to store your pipeline scripts. The dataset can also be added to this root folder. In this example, the folder structure is as follows:

FreeThrowProject
V3dPipelines
SPL-Open-Data-main

To start building your pipeline, navigate to pipelinebutton.jpg in Visual3D.

Creating the main Pipeline

1. Open up the Pipeline Workshop
2. Set the the pipeline folder path. Select 'Set_Pipeline_Parameter_To_Folder_Path' by clicking on the '»' in the workshop. This command selects the correct folder in your computer's directory. Change the PARAMETER_NAME to 'CALL_SCRIPT_SCRIPT_PATH', and PARAMETER_VALUE to the 'V3dPipelines' folder you just created.

Set_Pipeline_Parameter_To_Folder_Path
/PARAMETER_NAME=CALL_SCRIPT_SCRIPT_PATH
/PARAMETER_VALUE=C:\...\FreeThrowProject\V3dPipelines
;

3. Select 'Set_Pipeline_Parameter_To_List_Of_Files' by clicking on the '»' in the workshop. This command selects all the files within DATA_FOLDER. Set the PARAMETER_NAME to 'FILES', and the FOLDER to the subjects data folder (P0001). As the data are .json files, we will set FILE_MASK to *.json to select all of the .json files.

Set_Pipeline_Parameter_To_List_Of_Files
/PARAMETER_NAME= FILES
/FOLDER=C:\...\FreeThrowProject\SPL-Open-Data-main\basketball\freethrow\data\P0001
/FILE_MASK=*.json
;

4. Before running this section, create a folder named “P0001Processed” within your computer's directory.

FreeThrowProject
V3dPipelines
SPL-Open-Data-main
basketball
freethrow
data
P0001
P0001Processed

With all the files loaded into the pipeline, the next step is to run the for-loop that creates .cmz files. To create a loop, add the command 'For_Each', followed by 'End_For_Each', which closes the loop. The ITERATION_PARAMETER_NAME should be set to 'INDEX' for both.

For_Each
/ITERATION_PARAMETER_NAME= INDEX
/ITERATION_PARAMETER_COUNT_NAME=COUNT
/ITEMS= ::FILES
;

End_For_Each
/ITERATION_PARAMETER_NAME= INDEX
;

Inside the loop, we will create a new file, open it, then save the file. These commands should go between 'For_Each' and 'End_For_Each'. Ensure the FOLDER in the “File_Save_As” command is the correct file path to the folder created

File_New
;

File_Open
/FILE_NAME= ::INDEX
;

File_Save_As
/FILE_NAME=TRIAL&::COUNT
/FOLDER=C:\...\FreeThrowProject\SPL-Open-Data-main\basketball\freethrow\data\P0001Processed\
;

Save your pipeline as '0_call_scripts.v3s', under your pipeline folder.

FreeThrowProject
V3dPipelines
0_call_sripts.v3s

Make sure the pipeline is saved, before hitting 'Clear Pipeline'. We will come back to this script after building the other scripts.

Assigning Tags to Data

The next step in this pipeline will create commands to assign tags to each free throw attempt based on its outcome using the information provided in the MLSE dataset. In order to support the following steps in this tutorial, this step in the pipeline will tag each shot as made or missed and determine whether errant shots were right or left of the intended target.

The following pipeline commands will be saved under '1_assign_tags.v3s', so be sure to start with a blank Main Pipeline.

1. To assign a tag the 'Assign_Tags_To_Files' command is used. First we will tag shots based on whether they were made or missed.

Assign_Tags_To_Files
/MOTION_FILE_NAMES =ALL_FILES
/QUERY= PARAMETERS::MLSE::RESULTS="made"
/TAGS= Made
;

Assign_Tags_To_Files
/MOTION_FILE_NAMES =ALL_FILES
/QUERY= PARAMETERS::MLSE::RESULTS="missed"
/TAGS= Missed
;

2. Next, the 'Assign_Tags_To_Files' is used again to tag shots as being missed to the left or right side of the middle of the rim. To exaggerate the results, we will use shots that land +/- 3 inches away from the centre of the net.

Assign_Tags_To_Files
/MOTION_FILE_NAMES = ALL_FILES
/QUERY=(PARAMETERS::MLSE::LANDING[1])<-3
/TAGS= HoopLeft
;

Assign_Tags_To_Files
/MOTION_FILE_NAMES = ALL_FILES
/QUERY=(PARAMETERS::MLSE::LANDING[1])>3
/TAGS= HoopRight
;

Now each shot has successfully been tagged as being made or missed, and select shots have been labelled if it landed to the left/right.

Save this pipeline as '1_assign_tags.v3s' in your pipeline folder. Clear the Main Pipeline.

Event Tags

In biomechanical data analysis it is necessary to have defined events such as 'start' and 'stop' where the movements are consistent and the data can be normalized within those events. The right hand centre of gravity position was used as the event indicator. The start of the free throw was defined as the point when the right hand reached its lowest position in the z-direction (up from the floor), and the end of the follow-through was marked by the right hand reaching its highest point, this is a repeatable motion used for consistent analysis across all trials. See the gif below for a visual and graph of the start and end of the repeatable free throw motion.

The start of the trial shown in green, phase change in red, and the end of the trial in blue.

1. Add 'Event_Global_Minimum' captures the global minimum center of gravity position of the right hand.

Event_Global_Minimum
! name the event
/RESULT_EVENT_NAME=START
/SIGNAL_TYPES=KINETIC_KINEMATIC
! right hand
/SIGNAL_FOLDER=P0001:RHA
! center of gravity 
/SIGNAL_NAMES=CGPOS
! z-component
/SIGNAL_COMPONENTS=Z
;

2. Add 'Event_Global_Maximum' captures the global maximum center of gravity position of the right hand.

Event_Global_Maximum
/RESULT_EVENT_NAME=END
/SIGNAL_TYPES=KINETIC_KINEMATIC
/SIGNAL_FOLDER=P0001:RHA
/SIGNAL_NAMES=CGPOS
/SIGNAL_COMPONENTS=Z
;

Separating the shooting phase: The typical free throw motion can be separated into two distinct phases, not dissimilar from a counter jump. There is a loading phase and a release phase. The loading phase consists of storing energy in the knee, wrist, and elbow joints through simultaneous knee flexion, elbow flexion and wrist extension. The release phase sees the straightening of these joints leading to the release of the ball.

For this tutorial the transition between the loading and release phases was subjectively chosen by the point at which the distal portion of the thigh segment is at a minimum, to replicate the deepest portion of the squat.

3. Select Event Creation add “Event_Global_Minimum” to find the min vertical position of the distal end of the right thigh segment (RTH). By setting the EVENT_SEQUENCE to 'START+END', we will only take the global minimum within the start and end events which we previously defined.

Event_Global_Minimum
/RESULT_EVENT_NAME=LAUNCH_PHASE
/SIGNAL_TYPES=KINETIC_KINEMATIC
/SIGNAL_FOLDER=P0001:RTH
/SIGNAL_NAMES=DistEndPos
/SIGNAL_COMPONENTS=Z
/EVENT_SEQUENCE=START+END
;

Save the pipeline as '2_define_events.v3s' under your pipelines folder and clear the Main Pipeline.

Computing Joint Angles

Now that the beginning and end of our shooting motion has been defined, as well as the results of each shot, we can go about computing the important joint angles to perform further investigative analysis. For our purposes we will be computing the wrist, elbow, shoulder of the subject's shooting arm.

1. Select Model Based Data Computation add “Compute_Model_Based_Data” to find each joint angle.

Compute_Model_Based_Data
/RESULT_NAME=RightWristAngle
/SUBJECT_TAG=ALL_SUBJECTS
/FUNCTION=JOINT_ANGLE
/SEGMENT=RHA
/REFERENCE_SEGMENT=RFA
/RESOLUTION_COORDINATE_SYSTEM=
;

Computing Joint Angle Velocity

This step is optional, if you'd like to make a signal-signal plot using the wrist and elbow joint angular velocities, see the appendix.

1. Select Model Based Data Computation add “Compute_Model_Based_Data”, select 'JOINT_VELOCITY'

Compute_Model_Based_Data
/RESULT_NAME=RightWristAngVel
/SUBJECT_TAG=ALL_SUBJECTS
/FUNCTION=JOINT_VELOCITY
/SEGMENT=RHA
/REFERENCE_SEGMENT=RFA
/RESOLUTION_COORDINATE_SYSTEM=RFA
;

Below is a table with all the “Compute_Model_Based_Data” commands that will be needed to compute all joint angles, and angular velocities needed. More on reference segments can be found here, Default Joint Names.

Compute_Model_Based_Data Segment Reference Segment Resolution Coordinate System
RightWristAngle RHA RFA -
RightElbowAngle RFA RAR -
RightShoulderAngle RAR RTX -
RightWristAngVel RHA RFA RFA
RightElbowAngVel RFA RAR RAR
RightShoulderAngVel RAR RTX RTX

Save the pipeline as '3_compute_model_based_data.v3s' and clear the Main Pipeline.

Calling the scripts

Finally, we will go back to our original pipeline. Load in '0_call_scripts.v3s'. Inside our loop, after we have opened our file, we want to execute a series of commands on the file.

1. 'Select_Active_File' command. This command is run first to select the file to be updated.

Select_Active_File
/FILE_NAME=ALL_FILES
;

2. 'Call_Script' command. This command will call our scripts which we have written. Simply input the name of your script, followed by the path to the pipeline folder where the scripts are saved. We created 'CALL_SCRIPT_SCRIPT_PATH' as a pipeline path name in the beginning of the tutorial.

Call_Script
/SCRIPT_FILE_NAME=1_assign_tags.v3s
/SCRIPT_PATH=::CALL_SCRIPT_SCRIPT_PATH
;

Call_Script
/SCRIPT_FILE_NAME=2_define_events.v3s
/SCRIPT_PATH=::CALL_SCRIPT_SCRIPT_PATH
;

Call_Script
/SCRIPT_FILE_NAME=3_compute_model_based_data.v3s
/SCRIPT_PATH=::CALL_SCRIPT_SCRIPT_PATH
;

All of the commands required to effectively process our data are now included in the four pipelines. The completed pipelines should look like this:

0_call_scripts.v3s:

  • Set_Pipeline_Parameter_To_Folder_Path
  • Set_Pipeline_Parameter_To_List_Of_Files
  • For_Each
  • File_New
  • File_Open
  • Select_Active_File
  • Call_Script
  • Call_Script
  • Call_Script
  • File_Save_As
  • End_For_Each

1_assign_tags.v3s:

  • Assign_Tags_To_Files
  • Assign_Tags_To_Files
  • Assign_Tags_To_Files
  • Assign_Tags_To_Files

2_define_events.v3s:

  • Event_Global_Minimum
  • Event_Global_Maximum
  • Event_Global_Minimum

3_compute_model_based_data.v3s:

  • Compute_Model_Based_Data
  • Compute_Model_Based_Data
  • Compute_Model_Based_Data
  • Compute_Model_Based_Data
  • Compute_Model_Based_Data
  • Compute_Model_Based_Data

Splitting the pipeline commands into 3 separate files makes the script easier to follow and simplifies future edits and/or debugging.

Using Sift for Statistical Analysis and Data Visualization

Sift will be used to perform important statistical analysis on our processed free throw files and produce the corresponding visualizations. This is essential to drawing the appropriate conclusions from our investigation into shooting arm mechanics.

Load "ProcessedFiles"

To load the processed files into sift, select Load Library. Select the folder with the containing your ProcessedFiles.

Building Query Definitions

In order to properly identify all data groups for this tutorial a total of 27 queries will be needed, this includes makes, left misses, and right misses in the x, y, and z planes for each shooting arm joint. The completed query file can be downloaded here for convenience: Query Definitions. To complete the tutorial manually follow the steps below.

1. Navigate to the Explore tab on the left and select the Query Builder. Click the plus sign beside “Queries” to add a new query definition and name it “Wrist Angle X Made”, click save.
2. In the conditions list below your new query add a new condition using the +. Name the condition “Right X”
a. Under the “Signals” tab select the options shown below. This command will find the right wrist angle on all made shots in the x direction for all cmz files (each trial) and store the data in “Wrist Angle X Made”.

b. Under the “Events” tab select the following options. To add an event to the sequence, click the right hand arrow. By adding the event sequence = START, LAUNCH_PHASE and END, only the angles within the START and END events will be stored. Ensure Normalize Data Points is checked, as well as a Cubic spline type with 101 points.

c. Under the “Refinement” tab select the following below. Since only the made shots are being analyzed, ensure that the made tag is selected. For misses ensure that Missed is selected as well as the appropriate left or right option.
d. Click Save at the bottom of the dialog box to save the query.
e. Repeat these steps for the remaining groups for each joint, making the appropriate modifications to your signals and refinements where necessary.
f. Click Calculate All Queries at the bottom of the dialog box to load all data.

Once all of the necessary queries have been built there should be 27 total queries with a Made, Missed Left and Missed Right group in the x, y, and z directions for the wrist, elbow, and shoulder joints.

Visualizing Joint Angles

The queries that we built allows us to view plots for each of the 27 groups we defined. To best visualize the differences between makes and left/right misses it makes the most sense to compare these groups for just one joint angle at a time.

1. In the explore tab select the 3 groups that you wish to compare. For this tutorial we'll start with Wrist Angle X Made, Wrist Angle X Missed left, and Wrist Angle X Missed Right.
2. Click Select All Workspaces on the left as well as Plot Group Mean and Plot Group Dispersion. Your graph should look similar to below.

Curve Registration

In order to produce accurate results, the curves must be registered to a global or local maximum or minimum event. This will show a better representation of amplitude variation. To learn more about curve registration, reference Curve Registration for Biomechanical Waveforms.

Since the most variability in joint angles occurs in the x-direction (flexion / extension), only the x curves need to be registered and plotted.

1. After loading your query, select 'Register Curves…'.

2. Check the 'Event Sequence' box. Ensure the event sequence is in the following order: (START, LAUNCH_PHASE, END).

3. Hit Register.

Principal Component Analysis in Sift

PCA is a useful tool for data visualization and identifying complexity in variation between data groups. Here we outline the basic steps used to perform PCA on our free throw shooting metrics, a more in-depth tutorial and description can be accessed here: PCA Tutorial.

1. Select the groups on the left that you wish to compare, we'll start with the left and right misses for the right wrist in X. Navigate to the PCA button on the top toolbar. This will open a dialogue box, enter the information shown below.

Repeat these steps for misses in the X direction for the elbow and shoulder joints, adjust the number of PCs for each such that >90% of variance is explained. This should be achieved by 6 PCs for the Elbow and 5 for the shoulder.

Now, by exploring the different tabs at the bottom of your screen you should be able to see several charts associated with your PCA like Variance Explained and Group Scores.

K-Means Clusters

Once PCA has been performed on the select groups we can use K-Means testing on the results. K-Means testing uses an unsupervised algorithm to create clusters of data with similar characteristics, a more detailed tutorial can be accessed by reading Running K-Means.

To perform K-Means on our results navigate to the Outlier Detection Using PCA button on the top tool bar. Select K-Means from the dropdown menu. This will generate a dialogue box, complete it like so for your wrist, shoulder and elbow joints.

Click Run K-Means and navigate to the Workspace Scores section of your Analyse tab. You should see a graph that looks similar to this:

To get a better picture of what trials each cluster holds we can use the cluster information box in the K-means dialogue box. Expand Associated Workspaces to see exactly which trials are in each cluster.

By comparing the cluster information for the wrist, shoulder and elbow misses we can see that certain clusters are more cleanly separated than others.

Statistical Parametric Mapping (SPM)

SPM is a statistical analysis method, originally used in neuroscience, that can be useful in determining the presence of a statistically significant differences between datasets. Here we will use it to compare left and right misses for each of our arm joints in order to determine factors leading to a missed shot. For a more complete explanation of SPM in sift please read Statistical Parametric Mapping.

To build the SPM first select the two groups you wish to compare from the groups list on the left. Next, navigate to the SPM button on the toolbar. Before building our SPM we must build a GLM. For the shoulder, fill out the dialogue box as shown below.

Now that a GLM has been built we can use it to complete SPM. Select the Statistics Tab at the bottom of your screen and click Compute SPM. Fill the dialogue box like so:

You should now see an SPM graph similar to the one below. Repeat the steps above for the wrist and elbow joints.

Results

Once the waveforms for makes, left misses, and right misses had been visualized for all 27 queries, subtle differences could be seen between the results for each joint angle based on shot result. The most significant differences could be seen in the flexion/extension patterns for each joint. As such, further analytical testing was conducted on left vs right misses and how they were impacted by shoulder, elbow, and wrist movement in the x direction. The null hypothesis stated that joint movement would be consistent across all shots, this was rejected by our SPM testing which showed small but statistically significant differences in shoulder, elbow, and wrist flexion for left and right misses during the release phase of the shooting motion. These differences were first identified using visual inspection of the signal time plots (below) and confirmed using K-clusters and statistical parametric mapping.

X direction signal-time plots (Wrist - Elbow - Shoulder)

K-means clusters

SPM Plots

Optional: Creating a Signal-Signal Plot in Sift

1. In Sift, under Plot Type, click the dropdown to select 'Signal-Signal Plot'.

2. Highlight all the signals in your query you would like to plot. You can either left-click below and drag your mouse to select multiple, or hold 'CTRL' while selecting what signals to plot.

3. Under Signal-Signal, select 'New Pair'. Use the drop down to select which signal should be plotted on the x- and y-axis. Select 'New Pair' for as many conditions that you would like to compare. Be sure not to unselect signals in the query, as the option to select them in the signal-signal pairs will no longer show up. This tutorial will have a plot for the 'Made' shots, as well as the 'Missed HL' and 'Missed HR' shots. Each row should represent a different condition, as shown in the following diagram:

Be sure to use the registered curves for this plot, to align the phases of the shot and account for the lack of time series information in the signal-signal plot.

4. Select 'Plot Group Mean' and 'Plot Group Dispersion', with the dispersion type set to 'Standard Deviation'. Click Refresh Plot, the resulting plot is shown below (though annotations have been added for readability):

The following query can be used to analyse the joint angular velocities Joint Angular Velocities Query. Following the same steps to produce the joint angle signal-signal plot, the wrist and elbow flexion angular velocities can be plotted as shown in the following graph:

Interpreting the signal-signal plot

Signal-signal plots in biomechanics are often used to assess the coordination of two joint angles throughout a cycle. We were interested in how the the wrist and elbow flexion angle and joint angular velocity relationship changed amongst the various conditions (made/missed left/missed right). The joint angle signal-signal plot shows the elbow angle remaining fairly consistent throughout the shot, while the deviations from the coordination pattern primarily occur at the wrist. In the angular velocity signal-signal plot, we see deviations in the coordination pattern for both of the missed results category. For misses on the right side, the wrist has a faster positive angular velocity upon receiving the ball.

Using the Sift CMD Line for automation

A way to speed up this process if you have a lot of data for multiple participants is by creating a script utilizing the Sift command line. To first open Sift in the command line, open Command Prompt and enter “C:\Program Files\Sift\Sift.exe” -NoGUI

Enter -help to see a list of commands that can be run.

To get more help in understanding certain commands and their required parameters you can refer to the HAS-Motion Sift command line section or enter a specific command followed by “help” into Sift. For example, running “-kmeans help” produces the following output:

To script the SIFT command line process a code editor application and the newest version of Python must be installed. In this tutorial the code editor Visual Studio Code is used. Python is just one method of automating processing through the Sift CLI, any other scripting or programming language can be used.

Below are the steps required to build and execute the SIFT command line script. The final code is rather lengthy, it can be downloaded here if neededCompleted Sift Automation Code. Completed Sift Automation Code. The code is designed to automate the all the steps done previously in this tutorial from creating the cmz files in Visual 3D, to running PCA analysis on the signals and conducting SPM tests in Sift. Ultimately all these steps below should be combined and be ran in your code editor of choice.

Required Libraries

1. Import the subprocesses library. This will allow you to run shell commands and manage external processes directly from Python.
2. Import the os library. This will allow you to have access to folders and files within your computer.
3. Import the tkinter library as well as filedialog from the ktinter import. This is used in prompting the user to select a folder.

   import subprocess
   import os
   import tkinter as tk
   from tkinter import filedialog
   from tkinter.filedialog import askdirectory

Selecting and accessing the work folder

1.The code will open a file explorer prompt and ask the user to select the folder with all the data. In the example in the image below, the folder that would be selected is the “introproj_testenv” as it contains the data for participant 1,2, and 3.

2.os.chdir() will change the working directory to the folder in the directory variable.

  directory = askdirectory(title ='Select Folder')
  os.chdir(directory)
  

1.This part of the code goes through your working folder and checks to see if the folders within it contain any .json files to be processed. For this specific project the raw data is in json form, if you are using any other file type be sure to change the .json with that file type.

  for folder,subfolders,files in os.walk(directory):
      has_json = any(file.endswith(".json") for file in files) #checks for json files

2. If the folder does have a .json file it will first create a variable “fileName” by taking the name of the folder it is working on. This will be used later in the Sift process when naming the project files produced in Sift.

  if has_json:
      fileName = os.path.basename(folder)    #Creates fileName based on name of folder

The next step after this is to run the Sift CMD line subprocess. In coding the indentation is very important as it defines the hierarchy of code blocks, so before we add the subprocess, ensure that the code formatting looks like this:

  import subprocess
  import os
  import tkinter as tk
  from tkinter import filedialog
  from tkinter.filedialog import askdirectory
  directory = askdirectory(title ='Select Folder')
  os.chdir(directory)
  for folder,subfolders,files in os.walk(directory):
      has_json = any(file.endswith(".json") for file in files) #checks for json files USERS MIGHT HAVE DIFF FILE TYPES
  
      if has_json:
          fileName = os.path.basename(folder)    #Creates fileName based on name of folder
          #SUBPROCESS STARTS HERE
              

Ensure that the indentation of your code follows the same format as the code above.

Executing Sift CMD line operations

1. The following part of the code is run in the command prompt. This cannot be done if the import subprocess was not done at the beginning of the code. First, Sift will be open in the command prompt which will allow for the specific Sift commands to be used. The first Sift command is going to be “-RunV3DCommand” which runs a single V3D pipeline command. The command that will be ran is to set the variable DEFAULT_DATA to the folder we are currently working on.

  subprocess.run([
      "C:/Program Files/Sift/Sift.exe",
      #Sets the default data folder to the folder that contains the json files to be processed
      "-RunV3DCommand", 
      "command", "Set_Default_Folders/DEFAULT_DATA="+folder+";",
      

*Note: Only one instance of the Sift command line can be run at once, if you are notified of this error ensure all other command line windows are closed and re-run

2.The following line “-RunV3D” is used to run a full V3D pipeline. For the parameter “script” in the code, paste the path to the desired pipeline. In order for the pipeline to work for the automation some changes must be made in the original pipeline that was used. The full pipeline with changes can be found here.

a) In the Set_Pipeline_Parameter_To_Folder_Path command, instead of having a the folder path, the variable “VISUAL3D_DEFAULT_DATA_FOLDER” will be used as the PARAMETER_VALUE. This will utilize the “-RunV3DCommand” that was done earlier, allowing the current folder set to be used in the pipeline

  Set_Pipeline_Parameter_To_Folder_Path
  /PARAMETER_NAME=FOLDER
  /PARAMETER_VALUE=VISUAL3D_DEFAULT_DATA_FOLDER
  ! /FROM_MOTION_FILE_IN_WORKSPACE=
  ! /PARAMETER_VALUE_SEARCH_FOR=
  ! /PARAMETER_VALUE_REPLACE_WITH=
  ! /PARAMETER_VALUE_APPEND=
  ! /SET_PROMPT=Select a directory
  ! /ALPHABETIZE=TRUE
  ;
     

b) To simplify the process, the cmz files will be saved to the folder in which the .json are found. In order to make this change make the folder parameter access the folder variable which we previously set as the DEFAULT_DATA_FOLDER

  File_Save_As
  /FILE_NAME=TRIAL&::COUNT
  /FOLDER=::FOLDER
  ! /SET_PROMPT=Save CMZ file as
  ! /SAVE_EMBEDDED_GRAPHICS=FALSE
  ! /CREATE_FOLDER_PATH=FALSE
  ;

c) OPTIONAL If you are not using .json files for your data you will also have to make changes to the pipeline as it is currently hardcoded to specifically process .json files. In the second command of the pipeline, Set_Pipeline_Parameter_To_List_Of_Files, you can change the FILE_MASK parameter to whichever file type you are using.

  Set_Pipeline_Parameter_To_List_Of_Files
  /PARAMETER_NAME= FILES
  /FOLDER= ::FOLDER
  ! /SEARCH_SUBFOLDERS=FALSE
  /FILE_MASK=*.json !INSERT YOUR DATA FILE TYPE
  ! /ALPHABETIZE=TRUE
  ! /RETURN_FOLDER_NAMES=FALSE
  ! /RETURN_RELATIVE_FILENAMES=FALSE
  ;

Now that the pipeline is set for automation, the following code can be added to the Python script:

      "-RunV3D",
      "script","c:/Users/alexh/Downloads/introproj_testenv/testenvpipelinesimplified.v3s", #Replace with your pipeline path   

3. Next Sift will load the library with the processed cmz files from the created processed folder. The code goes from the folder and searches the folders within it until it finds the processed folder with the .cmz files inside and proceeds with those .cmz files.

  "-LoadLib",
  folder, #LOCATION OF PROCESSED FILES  
  

4. After the library is loaded in, a query must be loaded in. The same query used earlier in this tutorial can be used. Set the path to that .q3d file at the parameter value.

   "-LoadQuery",
  "c:/Users/alexh\Downloads/freethrow_rightleftmiss.q3d",

Registering Curves

Now that the queries are built, the curves must be registered. You first select the desired signal using the command “-SelectSignals” and enter the signal name as the “group” parameter. To then register the selected signal, use the “-RegisterCurves” command, choose a name for the registered signal, and how it is going to be registered. In this case it is being synchronized using the event sequence.
Below is how it should look after doing this process for:
Wrist Angle X
Wrist Angle X Missed HL
Wrist Angle X Missed HR

  "-SelectSignals",
  "group",
  "Wrist Angle X",
      
  "-RegisterCurves", 
  "name", "Wrist Angle X Reg",
  "EventSequence", 
  "-SelectSignals",
  "group",
  "Wrist Angle X Missed HL",
      
  "-RegisterCurves", 
  "name", "Wrist Angle X Missed HL Reg",
  "EventSequence", 
  "-SelectSignals",
  "group",
  "Wrist Angle X Missed HR",
      
  "-RegisterCurves", 
  "name", "Wrist Angle X Missed HR Reg",
  "EventSequence",
  

GLM and SPM analysis

1.First select all the registered curves of the desired grouping. The “-Create GLM” command requires two parameters, the name of the GLM and how it is being grouped. Similar to earlier in the tutorial, these signals are being grouped by its group.

  "-SelectSignals", 
  "group","Wrist Angle X Reg",
  "group", "Wrist Angle X Missed HL Reg",
  "group", "Wrist Angle X Missed HR Reg",
  "-CreateGLM",
  "name", "Wrist X GLM",
  "grouping", "group", 

2. The command to do the SPM analysis requires for 6 parameters to be filled. “alpha” equates to the threshold, the name of the SPM graph, the GLM and two groups from it that you want to run the SPM analysis with, and if it is two-tailed or one-tailed.

  "-spm",
  "alpha","0.05",
  "name", "Wrist Angle X SPM",
  "glm","Wrist X GLM",
  "group1", "Wrist Angle X Missed HL Reg",
  "group2","Wrist Angle X Missed HR Reg",
  "twoTailed",

Please repeat the Registering curves and GLM and SPM for the following groups of signals if you would like the result to follow the earlier tutorial:
Elbow Angle X
Elbow Angle X Missed HL
Elbow Angle X Missed HR
Shoulder Angle X
Shoulder Angle X Missed HL
Shoulder Angle X Missed HR

Running a PCA Analysis

1. Running the PCA analysis is similar to the GLM and SPM. First select the desired signals then name the resulting PCA graph and select the number of PCs.

  "-SelectSignals", 
  "group", "Wrist Angle X Missed HL Reg",
  "group", "Wrist Angle X Missed HR Reg",
  "-RunPCA",
  "name","Wrist X PCA",
  "numPCs","6",

2. To run a K-Means cluster test fill out the following parameters as so:

  "-RunKMeans",
  "clusters","3",
  "customSeed","10",
  "iterations","5",
  "PCsVariance","95",
  "grouping","combined group",
  

Repeat these steps for the Elbow Angle Missed X signals and Shoulder Angle Missed X signals.

Saving the Sift Project

To save the project so that the results can be viewed, the Sift project will be saved as a .i3d file. The location of the save will be the same folder as the main work folder selected in the beginning. The resulting projects will be named with the same format, “siftcomputations” followed by the fileName created for the folder earlier in the code. “-exit.” will automatically close the Sift program once it is finished running the the command line script.

  "-SaveProject",
  directory+"\siftcomputations"+fileName+".i3d",
  "-exit"

The final Python script is rather lengthy. The full script can be downloaded here.

Conclusion

Using statistical analysis methods including PCA and SPM we were able to identify significant differences in wrist, elbow, and shoulder flexion/extension patterns contributing to horizontal inaccuracy when shooting free throws. PCA and visual analysis were used to identify which joint angles exhibited the most variance, SPM then helped to quantify these inconsistencies and identify exactly how the shot phases were impacted.

This research builds on existing work done to optimize free throw mechanics which primarily focuses on lower body mechanics and release height. Further analysis on a greater field of subjects could be used to identify if these patterns are consistent across different individuals and skill levels, which may be more applicable to basketball training and development.

References

[1]Cabarkapa D, Cabarkapa DV, Miller JD, Templin TT, Frazer LL, Nicolella DP, Fry AC. Biomechanical characteristics of proficient free-throw shooters-markerless motion capture analysis. Front Sports Act Living. 2023 Aug 2;5:1208915. doi: 10.3389/fspor.2023.1208915. PMID: 37601167; PMCID: PMC10436204. https://pmc.ncbi.nlm.nih.gov/articles/PMC10436204/ [2] Lees A, Barton G, Robinson M. The influence of Cardan rotation sequence on angular orientation data for the lower limb in the soccer kick. J Sports Sci. 2010 Feb;28(4):445-50. doi: 10.1080/02640410903540352. PMID: 20155569. https://pubmed.ncbi.nlm.nih.gov/20155569/

sift/tutorials/openbiomechanics_project/impact_shooting_arm_mechanics_free_throw_accuracy.txt · Last modified: 2025/09/17 15:02 by wikisysop