======Effects of Fatigue During Basketball Free Throws Using Statistical Analysis====== ====Abstract==== This tutorial demonstrates how to use **Visual3D** and **Sift** as tools to examine the effects of fatigue on lower body joint kinematics, specifically at the ankle, knee, and hip during basketball free throws. Using MLSE's markerless motion capture data, joint angles were computed across the trials to assess how movement changed as fatigue develops. Statistical analysis was done using SPM and ANOVA, the results revealed a consistent decrease in hip and knee flexion, along with reduced ankle dorsiflexion as the trials progressed. These changes suggest a diminished contribution from the lower body during the shooting motion under fatigue. Further analysis could explore potential compensations in upper-body joints. Follow along below to learn how this dataset was processed, visualized, and analyzed using **Visual3D** and **Sift**.\\ **What are the effects of fatigue on hip, knee, and ankle joint kinematics throughout 125 consecutive basketball free throw attempts?** ====Dataset & Relevant Links==== This tutorial will be using the public dataset made available by [[https://www.mlse.com/|MLSE]], it includes 125 trials of one non-professional athlete completing free throws within the span of 2-3 hours. The data was collected by **MLSE's Sports 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.\\ Dataset is available at the following link:[[https://has-motion.com/download/examples/Freethrow/SPL-Open-Data-main.zip|Dataset]]\\ In github navigate to **basketball/freethrow** and download the **data/P001** folder which contains the dataset.\\ {{:datamlse.png}}\\ 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 and the 27 pose marker positions used. 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 can be seen here, [[https://pubmed.ncbi.nlm.nih.gov/20155569/| Cardan Rotation]]. [1].\\ ====Processing Data in Visual3D==== Below are the steps required to build and execute the single pipeline needed to process the raw dataset. The final pipeline is rather lengthy, it can be downloaded here if needed, [[https://has-motion.com/download/examples/Freethrow/ProcessedFilePipeline.txt|Completed Pipeline]]. The pipeline is designed to automate specific commands that need to be applied across multiple files, streamlining the processing. Ultimately, all steps below should be combined and executed within one pipeline in Visual3D. To follow along, navigate to {{:pipelinebutton.jpg?48x48}} in **Visual 3D**. ===Converting Between .json and .cmz=== **1.** Open up the Pipeline Workshop\\ **2.** 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_VALUE** to the downloaded dataset within your own directory. Set_Pipeline_Parameter_To_Folder_Path /PARAMETER_NAME=FOLDER /PARAMETER_VALUE=C:\...\SPL-Open-Data-main\basketball\freethrow\data\P0001\ ! /FROM_MOTION_FILE_IN_WORKSPACE= ! /PARAMETER_VALUE_SEARCH_FOR= ! /PARAMETER_VALUE_REPLACE_WITH= ! /PARAMETER_VALUE_APPEND= ! /SET_PROMPT=Select a directory ! /ALPHABETIZE=TRUE ; **3.** Select 'Set_Pipeline_Parameter_To_List_Of_Files' by clicking on the '>>' in the workshop. This command selects all the files within **FOLDER** which have the file type .json. In this case, that is every file in the folder. Set_Pipeline_Parameter_To_List_Of_Files /PARAMETER_NAME= FILES /FOLDER= ::FOLDER ! /SEARCH_SUBFOLDERS=FALSE /FILE_MASK=*.json ! /ALPHABETIZE=TRUE ! /RETURN_FOLDER_NAMES=FALSE ! /RETURN_RELATIVE_FILENAMES=FALSE ; **4.** Before running this section, create a folder named "ProcessedFiles" within your computer's directory. Ensure the **FOLDER** in the "File_Save_As" command is the correct file path to the folder created. With all the files loaded into the pipeline, the next step is to run the for-loop that converts all the .json to .cmz files. This requires 5 commands: "For_Each", "File_New", "File_Open", "File_Save_As", "End_For_Each". For_Each /ITERATION_PARAMETER_NAME= INDEX /ITERATION_PARAMETER_COUNT_NAME=COUNT /ITEMS= ::FILES ; File_New ; File_Open /FILE_NAME= ::INDEX ! /FILE_PATH= ! /SEARCH_SUBFOLDERS=FALSE ! /SUFFIX= ! /SET_PROMPT=File_Open ! /ON_FILE_NOT_FOUND=PROMPT ! /FILE_TYPES_ON_PROMPT= ; File_Save_As /FILE_NAME=TRIAL&::COUNT /FOLDER=C:\...\SPL-Open-Data-main\basketball\freethrow\data\ProcessedFiles\ ! /SET_PROMPT=Save CMZ file as ! /SAVE_EMBEDDED_GRAPHICS=FALSE ! /CREATE_FOLDER_PATH=FALSE ; End_For_Each /ITERATION_PARAMETER_NAME= INDEX ; This pipeline itself will convert all the .json files to workspaces(.cmz) and can be run individually. But for consistency, the following commands will all be added to the for-loop, after 'File_Open' and before 'File_Save_As' ===Assigning Tags=== In this dataset, the primary variables analyzed are whether the subject made or missed the shot and the quarter of the session in which the free throw trial occurred. Tags are assigned to each trial for easier processing in **Sift**. Many of the tag commands are repeated in the pipeline, so each command will be shown here once and the order of the pipeline will be provided so that it can be built manually. If you are having difficulty recreating the pipeline, the complete pipeline is given at the beginning of this section of the tutorial. **1.** 'Select_Active_File' command. This command is run first to select the file to be tagged. Select_Active_File /FILE_NAME=ALL_FILES ! /QUERY= ! /SUBJECT_TAGS=NO_SUBJECT ; **2.** To assign a tag the 'Assign_Tags_To_Files' command is used. Assign_Tags_To_Files /MOTION_FILE_NAMES =ALL_FILES /QUERY= PARAMETERS::MLSE::RESULTS="missed" ! change this to "made" to collect the made shots /TAGS= missed ! change the tag to 'made' as well when collecting the made shots ; **3.**This subject completed 125 trials in total. To address the primary research question related to fatigue, the trials are divided into four sections (quarters), allowing each quarter to be analyzed independently and compared over time. Conditional statements are used to mark which quarter the trial took place. The quarters are: Q1 (Trial 1-31), Q2 (Trial 32-63), Q3 (Trial 64-94), Q4 (Trial 95-125).\\ **a.** For Q1 and Q4, the conditional statements are relatively simple and the expression is true if the iteration count is greater or less than the quarter number. Conditional_Statement /ITERATION_PARAMETER_NAME= QuarterOne /EXPRESSION= &::COUNT& <= 31 ! /AS_INTEGER=TRUE ; Assign_Tags_To_Files /MOTION_FILE_NAMES = ALL_FILES !/QUERY= /TAGS= Q1 ; Conditional_Statement_End /ITERATION_PARAMETER_NAME= QuarterOne ; **b.** For Q2 and Q3, nested conditional statements must be used to satisfy the lower and upper bounds. Conditional_Statement /ITERATION_PARAMETER_NAME= QuarterTwo /EXPRESSION= &::COUNT& >= 32 ! /AS_INTEGER=TRUE ; Conditional_Statement /ITERATION_PARAMETER_NAME= QuarterTwoIn /EXPRESSION= &::COUNT& <= 63 ! /AS_INTEGER=TRUE ; Assign_Tags_To_Files /MOTION_FILE_NAMES= ALL_FILES ! /QUERY= /TAGS= Q2 ; Conditional_Statement_End /ITERATION_PARAMETER_NAME= QuarterTwoIn ; Conditional_Statement_End /ITERATION_PARAMETER_NAME= QuarterTwo ; **4.** The order of the pipeline in its current state: * Set_Pipeline_Parameter_To_Folder_Path * Set_Pipeline_Parameter_To_List_Of_Files * For_Each * File_New * File_Open * Select_Active_File * Assign_Tags_To_Files * Assign_Tags_To_Files * Conditional_Statement * Assign_Tags_To_Files * Conditional_Statement_End * Conditional_Statement * Conditional_Statement * Assign_Tags_To_Files * Conditional_Statement_End * Conditional_Statement_End * Conditional_Statement * Conditional_Statement * Assign_Tags_To_Files * Conditional_Statement_End * Conditional_Statement_End * Conditional_Statement * Assign_Tags_To_Files * Conditional_Statement_End * File_Save_As * End_For_Each ===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. In this free throw dataset, a large portion of the time-series data is spent with the subject catching the pass and walking to the free throw line. This is not important data to answer the research question so it is cut out in this section. The right hand center 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.\\ {{:visual3d:tutorials:event_freethrow.gif?}} **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 ! /FRAME_OFFSET=0 ! /TIME_OFFSET= ! /EVENT_SEQUENCE= ! /EXCLUDE_EVENTS= ! /EVENT_SEQUENCE_INSTANCE=0 ! /EVENT_SUBSEQUENCE= ! /SUBSEQUENCE_EXCLUDE_EVENTS= ! /EVENT_SUBSEQUENCE_INSTANCE=0 ! /THRESHOLD= ; **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 ! /FRAME_OFFSET=0 ! /TIME_OFFSET= ! /EVENT_SEQUENCE= ! /EXCLUDE_EVENTS= ! /EVENT_SEQUENCE_INSTANCE=0 ! /EVENT_SUBSEQUENCE= ! /SUBSEQUENCE_EXCLUDE_EVENTS= ! /EVENT_SUBSEQUENCE_INSTANCE=0 ! /THRESHOLD= ; **3.** This step isn't required, but for interest, an event between can be added that will put an event at the midpoint between the start and end events. Event_Between /NEW_EVENT_NAME=MIDSHOT ! /RANGE_INSTANCE=0 !includes all events /EVENT_SEQUENCE=START+END ! /EXCLUDE_EVENTS= ! /FRAME_OFFSET=0 ! /TIME_OFFSET= ! /PERCENT_OFFSET= ; **4.** All 3 of these event commands can be added in order after the last 'Conditional_Statement_End' and before the 'File_Save_As' in the pipeline. Visualization of the **START** and **END** events can be seen below:\\ ^**START**^**END**^ | {{:start_event_position.png?350x640}} | {{:end_pos.png?350x640}} | ===Computing Joint Angles=== Now that all the tags and events are created, the final step is to calculate kinematic variables and specifically in this case, joint angles. The joint angles for the lower limb model will be calculated (ankle, knee, and hip joint).\\ **1.** Select **Model Based Data Computation** add "Compute_Model_Based_Data" to find each joint angle (ankle, knee, and hip). Compute_Model_Based_Data /RESULT_NAME=Right Ankle Angle /SUBJECT_TAG=ALL_SUBJECTS /FUNCTION=JOINT_ANGLE /SEGMENT=RFT /REFERENCE_SEGMENT=RSK /RESOLUTION_COORDINATE_SYSTEM= ! /USE_CARDAN_SEQUENCE=FALSE ! /NORMALIZATION=FALSE ! /NORMALIZATION_METHOD= ! /NORMALIZATION_METRIC= ! /NEGATEX=FALSE ! /NEGATEY=FALSE ! /NEGATEZ=FALSE ! /AXIS1=X ! /AXIS2=Y ! /AXIS3=Z ! /TREADMILL_DATA=FALSE ! /TREADMILL_DIRECTION=UNIT_VECTOR(0,1,0) ! /TREADMILL_SPEED=0.0 ; Below is a table with all the "Compute_Model_Based_Data" commands that will be needed to compute all angles needed. More on reference segments can be found here, [[https://wiki.has-motion.com/doku.php?id=visual3d:documentation:pipeline:model_based_data_commands:default_joint_names|Visual3D Reference Segments]]. ^ Compute_Model_Based_Data ^ Segment ^ Reference Segment ^ | Right Ankle Angle | RFT | RSK | | Left Ankle Angle | LFT| LSK| | Right Hip Angle | RTH | RPV| | Left Hip Angle | LTH| RPV| | Right Knee Angle | RSK | RTH| | Left Knee Angle | LSK| LTH| ===Completed Pipleline=== The pipeline should now have the following components:\\ * Set_Pipeline_Parameter_To_Folder_Path * Set_Pipeline_Parameter_To_List_Of_Files * For_Each * File_New * File_Open * Select_Active_File * Assign_Tags_To_Files * Assign_Tags_To_Files * Conditional_Statement * Assign_Tags_To_Files * Conditional_Statement_End * Conditional_Statement * Conditional_Statement * Assign_Tags_To_Files * Conditional_Statement_End * Conditional_Statement_End * Conditional_Statement * Conditional_Statement * Assign_Tags_To_Files * Conditional_Statement_End * Conditional_Statement_End * Conditional_Statement * Assign_Tags_To_Files * Conditional_Statement_End * Event_Global_Minimum * Event_Global_Maximum * Compute_Model_Based_Data * Compute_Model_Based_Data * Compute_Model_Based_Data * Compute_Model_Based_Data * Compute_Model_Based_Data * Compute_Model_Based_Data * File_Save_As * End_For_Each ====Analysis & Visualization in Sift==== Open a blank workspace in **Sift**, the processed __cmz files__ created from **Visual3D** will be used to analyze the ankle, knee, and hip joint angles to see the effects of fatigue. **Sift** will produce visualizations to be able to better understand the results. ===Load "ProcessedFiles" & Build Query Definitions=== To load the processed files into sift, select {{:sift_library_load.png?48x48}} **Load Library**. Select the folder with the contained processed files, **ProcessedFiles**.\\ Since there are numerous queries needed, the following file can be used (ensure the file is saved as a **.q3d file** - can download as a txt file and rename to .q3d), [[https://has-motion.com/download/examples/Freethrow/ProcessedQueries.q3d|Completed Queries]]. Instead of manually doing the process below for all, click **Load Query Definitions** at the top of the dialog box and select the downloaded file and click **Calculate All Queries.** If completing manually, when the files are loaded navigate to the Explore tab on the left and select the Query Builder{{:sift_query_builder.png?48x48}}\\ The analysis requires the ankle, knee, and hip angles in all directions (X,Y,Z) and separated into four groups based on fatigue levels (Q1, Q2, Q3, Q4) made into separate queries. Below is an example on how to manually create one of these queries. \\ **1.** Click the plus sign beside "Queries" to add a new query definition and name it **"Q1 Ankle Angle X"**, click save.\\ **2.** Name the condition **"Left X"**\\ **a.** Under the "Signals" tab select the following below. This command will find the left ankle angle in the x direction for all cmz files (each trial) and store the data in **"Q1 Ankle Angle X".**\\ {{:q1.png?350}}\\ **b.** Under the "Events" tab select the following below. To add an event to the sequence, click the right hand arrow. By adding the event sequence = **START** and **END**, only the left ankle 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. \\ {{:q2.png?350}}\\ **c.** Under the "Refinement" tab select the following below. Since only the made shots are being analyzed, the **made** tag is selected as well as the **Q1** tag since only the beginning shots are needed for this query.\\ {{:q3.png?350}}\\ **d.** Click Save at the bottom of the dialog box to save the query.\\ **e.** To finish this query, the right ankle needs to have a condition within the **Q1 Ankle Angle X** query. Select the plus sign beside **Conditions** and repeat the above process. Only difference is ensuring **"P0001: Right Ankle Angle"** is selected as the **Signal Name** in the **Signals** tab.\\ **f.** Click **Calculate All Queries** at the bottom of the dialog box to load all data.\\ After all queries are made, there should be 9 queries for each quarter (36 total). For example:\\ -Q1 Ankle Angle X\\ -Q1 Ankle Angle Y\\ -Q1 Ankle Angle Z\\ -Q1 Knee Angle X\\ -Q1 Knee Angle Y\\ -Q1 Knee Angle Z\\ -Q1 Hip Angle X\\ -Q1 Hip Angle Y\\ -Q1 Hip Angle Z\\ ===Registering the Curves=== 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 [[https://wiki.has-motion.com/doku.php?id=sift:curve_registration:curve_registration_for_biomechanical_waveforms&s[]=register|Sift Curve Registration]]\\ Since the most variability in joint angles occurs in the x-direction (flexion or compression), only the x curves need to be registered and plotted.\\ The following curves need to be registered:\\ -**Q1, Q2, Q3, Q4 Ankle Angle X**\\ -**Q1, Q2, Q3, Q4 Knee Angle X**\\ -**Q1, Q2, Q3, Q4 Hip Angle X**\\ Select **Register Curves** at the bottom left of the page, to register a global maximum or minimum follow:\\ {{:global.png?350}}\\ Select **Register Curves**, to register a local maximum or minimum follow:\\ {{:local.png?350}}\\ Below is a table with each group and the associated registration type.\\ ^ Groups ^ Registration Type ^ | Q1, Q2, Q3, Q4 Ankle Angle X | Global Max | | Q1, Q2, Q3, Q4 Knee Angle X | Global Min | | Q1, Q2, Q3, Q4 Hip Angle X | Local Max between 20-40 | ===Plotting in Sift=== To view the effects of fatigue, Q1 and Q4 data of the ankle, knee, and hip angles will be plotted. \\ *In the **Explore** tab, right click on both **Q1AnkleAngleX_Registered** and **Q4AnkleAngleX_Registered** in the __Plotting Controls__. *__Select All Workspaces__ above the Workspaces box. *In the __Plotting Controls__ tab, select **Plot Group Mean** and **Plot Group Dispersion.** Repeat this process for the knee and hip. To change the style of the plot, refer to [[https://wiki.has-motion.com/doku.php?id=sift:tutorials:export_results#visualize_the_groups|Visualization in Sift]] to learn more about altering the plot settings. The plots should look similar to below:\\ ^ Ankle ^ Knee ^ Hip ^ | {{:sift:tutorials:ankle_angle.jpg?350}} | {{:sift:tutorials:knee_plot.jpg?350}} | {{:sift:tutorials:hip_plot.jpg?350}} | ===Statistical Parametric Mapping (SPM) & ANOVA Analysis=== **SPM** is a statistical analysis method that will show if there are significant statistical differences in the processed dataset. To learn more about SPM reference, [[https://wiki.has-motion.com/doku.php?id=sift:statistical_parametric_mapping:using_statistical_parametric_mapping_in_biomechanics|SPM in Biomechanics]]\\ 1. Control-right click on the two registered groups being analyzed, navigate to the **Analyze** tab and select the **Mapping** tab at the bottom of the **INFO** box and select **Crete GLM**. Follow the below image for the ankle, knee, and hip.\\ {{:glm.png?350}}\\ 2. Navigate to the **Statistics** tab at the bottom of the **INFO** box and select **Compute SPM** - follow the image below.\\ {{:spm.png?350}}\\ The above steps can be followed for the ankle, knee, and hip to see if there are statistically significant differences in each joint as fatigue increases. A one way ANOVA test can be conducted on all four sections of free throws (Q1, Q2, Q3, Q4). The ANOVA test compares the means of the four groups to determine if there is a statistically significant difference between them. In order to do this, follow the above SPM steps but instead of selecting **Two Sample T-Test**, select ** One-Way ANOVA**. Compute the SPM using the ANOVA GLM. ====Results==== After analyzing the motion capture data, clear changes in lower-body joint kinematics were observed across all trials. The null hypothesis, mean joint angles remain consistent before and after fatigue was rejected following statistical analysis. Specifically, there was a reduction in hip and knee flexion along with decreased dorsiflexion in the ankle. This suggests an overall decline in lower-body usage as fatigue developed. To statistically find the relevance of these outcomes, SPM and ANOVA tests were conducted and are shown below. These tests confirmed the significant differences in joint angles as the trials progressed. ==SPM Results== The associated t-values for each SPM result for the ankle, knee, and hip respectively are below:\\ | ^ SPM t-values ^ Portion of Motion that is Significant ^ ^ Ankle | 2.72 | 15% - 30% | ^ Knee | 2.83 | 12% - 80% | ^ Hip | 2.83 | 12% - 75% | The ankle SPM showed a significant reduction in ankle dorsiflexion between Q1 and Q4, this can be seen in the "Plotting in Sift" section. A significant cluster can be seen between **15% and 30%** of the free throw movement, where the SPM t-value threshold was exceeded. The maximum t-value was **2.72** showing a significant difference in joint angle consistent with fatigue-related motion changes. Similarly, the knee and hip both showed significant reduction in flexion as the trials progressed. Both have t-values of **2.83** and occurred between **12-80%** for the knee and **12-75%** for the hip. Since the clusters were continuous and large this suggests a consistent change in lower body mechanics over majority of the free throw motion as fatigue progressed.\\ To better visualize the section of the movement where there is a significant difference in flexion, reference the yellow line on the graphs in the second row below.\\ ^ Ankle SPM ^ Knee SPM ^ Hip SPM ^ | {{:ankle_spm.jpg?350}} | {{:knee_spm.jpg?350}} | {{:hip_ttest_spm.jpg?350}} | | {{:ankle_angle_edit.jpg?350}} | {{:knee_plot_edit.jpg?350}} | {{:hip_plot_edit.jpg?350}} | ==ANOVA== The ANOVA test results can be seen below with F values for the ankle, knee, and hip.\\ ^ Ankle ANOVA F-value ^ Knee ANOVA F-value ^ Hip ANOVA F-value ^ | 4.76 | 4.97 | 4.92 | A larger F-value indicates that the group means have more variance relative to variability within each group. These results indicate that all three joints showed significant changes in the movement pattern over time with a consistent reduction in flexion observed in later trials. To further understand the concept of an ANOVA test, reference [[https://pmc.ncbi.nlm.nih.gov/articles/PMC5296382/|Understanding one-way ANOVA using conceptual figures]].\\ ^ Ankle ANOVA ^ Knee ANOVA ^ Hip ANOVA ^ | {{:ankle_anova_spm.jpg?350}} | {{:knee_anova_spm.jpg?350}} | {{:hip_anova_spm.jpg?350}} | ====Conclusions==== This tutorial demonstrated that fatigue significantly impacts lower body joint kinematics during repeated basketball free throw attempts in one session. Motion capture data, courtesy of MLSE, revealed a consistent reduction in ankle, hip, and knee flexion as fatigue developed. SPM and ANOVA tests were used to identify that there is significant clusters of reduced joint angles across the motion for the hip and knee, and a smaller reduction seen in the ankle. The ANOVA test confirmed the SPM test results.\\ These results suggests the importance of lower-body endurance in being able to maintain consistent free throw mechanics. Further research could investigate if upper body joints compensate for the reduction in flexion in the lower body. This could aid in the creation of strategies to reduce fatigue-related performance decline. ====References==== [1] 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/]]