Skip to content

Commit d2d889c

Browse files
Enhance example.md with 3D part and data analysis steps
Added detailed instructions for 3D data generation and output file processing.
1 parent a3dae0c commit d2d889c

1 file changed

Lines changed: 122 additions & 0 deletions

File tree

example.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# 2D Part
12
# STEP 1: Install Anaconda
23
Download the executable from [this link](https://www.anaconda.com/download) then follow the instructions there to install Anaconda.
34

@@ -39,3 +40,124 @@ Go to the next tab, the "Evaluate network" tab (6th tab). I recommend checking "
3940
Now, you can move on to the "Analyze videos" tab (7th tab). The video should already be selected, but if it is not, you can re-add it.
4041

4142
:warning: **Make sure to check the "Save result(s) as csv" box**. Now you can click "Analyze Videos" and wait for it to complete.
43+
44+
# 3D Part
45+
Now, repeat the above process for both of the 2d camera views, then you can generate the 3d data, using the following code:
46+
```
47+
import deeplabcut
48+
import matplotlib
49+
config_path3d = '/home/nexus/Downloads/analyze_all_videos/DLC_3D_calibration/calibration-Susan-2022-09-01-3d/config.yaml' # edit this to your config path
50+
# if creating a new 3D calibration
51+
# config_path3d = deeplabcut.create_new_project_3d('calibration','Susan',num_cameras=2)
52+
# deeplabcut.calibrate_cameras(config_path3d, cbrow =5,cbcol =7,calibrate=False,alpha=0.9)
53+
# deeplabcut.calibrate_cameras(config_path3d, cbrow =5,cbcol =7,calibrate=True,alpha=0.9)
54+
# deeplabcut.check_undistortion(config_path3d, cbrow=5, cbcol=7)
55+
56+
video_path = '/home/nexus/Downloads/20230308/DLC_3D'
57+
58+
deeplabcut.triangulate(config_path3d,video_path,filterpredictions=True, videotype='mp4',save_as_csv =True)
59+
```
60+
61+
# Analysis of Data
62+
## STEP 1: Create a new Conda environment
63+
In an Anaconda terminal, run `conda create -n "mousearm-test python=3.11 -y"` or any environment name.
64+
Activate the environment with `conda activate mousearm-test`.
65+
66+
## STEP 2: Install opensim via conda
67+
**Windows/Linux**: `conda install -c opensim-org opensim`.
68+
**macOS (Apple Silicon)**: `CONDA_SUBDIR=osx-64 conda install -c opensim-org opensim`.
69+
70+
## STEP 3: Go to your Documents folder
71+
**Windows**: `cd %USERPROFILE%\Documents`.
72+
**Linux/macOS**: `cd ~/Documents`.
73+
74+
## STEP 4: Clone this git repo and install the library
75+
Run the following in the Anaconda terminal:
76+
```
77+
# Using SSH:
78+
git clone git@github.com:Al-Borno-Lab/mousearm.git
79+
80+
# OR using HTTPS:
81+
git clone https://github.com/Al-Borno-Lab/mousearm.git
82+
83+
cd mousearm
84+
pip install uv'
85+
86+
uv pip install -e .
87+
```
88+
89+
## STEP 5: Place your data folder anywhere with the following format (any number of reachsets)
90+
```
91+
Data/
92+
├── reachset_1/
93+
│ └── kinematics_1.csv
94+
└── reachset_2/
95+
└── kinematics_1.csv
96+
```
97+
Then, in a separate anaconda terminal, cd into the parent directory of the Data folder.
98+
99+
In a new python file in the same folder as the Data folder, enter:
100+
```
101+
from mousearm.simulate import run_simulation
102+
run_simulation("Data", nReachSets=2) # Adjust nReachSets accordingly
103+
```
104+
Then, run it using `python run ` from the parent directory of the Data folder.
105+
106+
# Data Formatting
107+
Process the motion capture data through [DeepLabCut](https://github.com/DeepLabCut/DeepLabCut). The output file will have more data than necessary, so delete everything except time, paw (x,y,z), wrist (x,y,z), shoulder (x,y,z), elbow (x,y,z). At the end, the csv file should look like the following:
108+
![Example input file](/images/image_2025-12-31_145620844.png)
109+
110+
After formatting, the data folder should be formatted like this:
111+
```
112+
RawData/
113+
└── reachsets/
114+
├── reachset_1/
115+
│ └── kinematics_1.csv
116+
├── reachset_2/
117+
│ └── kinematics_1.csv
118+
└── ...
119+
```
120+
121+
# Output File Processing
122+
123+
The important output files are muscle_solution and the muscle_kinematics:
124+
* muscle_solution shows the solution that the model found for the movement. These can be visualized in OpenSim to observe the movement and predicted muscle actuations.
125+
* muscle_kinematics shows the difference between the captured movement and the movement predicted by the model
126+
127+
These files can both be imported into a pandas dataframe for further analysis with the below python code. The directory should be structured like this:
128+
```
129+
RawData/
130+
└── reachsets/
131+
├── reachset_1/
132+
│ ├── muscle_solution_adjusted_kinematics_1.sto
133+
│ └── muscle_kinematics_adjusted_kinematics_1.csv
134+
├── reachset_2/
135+
│ ├── muscle_solution_adjusted_kinematics_1.sto
136+
│ └── muscle_kinematics_adjusted_kinematics_1.csv
137+
└── ...
138+
```
139+
```
140+
import pandas as pd
141+
import glob
142+
import numpy as np
143+
base_dir = "../../RawData/reachsets/" # Adjust this path to yours
144+
save_dir = "../../Data/" # Adjust this path to yours
145+
mcolnames = ["time", "/jointset/shoulder/elv_angle/value", "/jointset/shoulder/extension_angle/value", "/jointset/shoulder/rotation_angle/value", "/jointset/humerus_ulna/elbow_flex/value", "/jointset/ulna_radius_pj/radius_rot/value", "/jointset/wrist/wrist_angle/value", "/jointset/shoulder/elv_angle/speed", "/jointset/shoulder/extension_angle/speed", "/jointset/shoulder/rotation_angle/speed", "/jointset/humerus_ulna/elbow_flex/speed", "/jointset/ulna_radius_pj/radius_rot/speed", "/jointset/wrist/wrist_angle/speed", "/forceset/Pectoralis_Clavicle_Head/activation", "/forceset/Biceps_Short_Head/activation", "/forceset/Biceps_Long_Head/activation", "/forceset/Deltoid_Medial/activation", "/forceset/Triceps_Lat_Head/activation", "/forceset/Triceps_Long_Head/activation", "/forceset/Brachialis_Proximal_Head/activation", "/forceset/Brachialis_Distal_Head/activation", "/forceset/Anconeus/activation", "/forceset/Deltoid_Posterior/activation", "/forceset/Anconeus_Short_Head/activation", "/forceset/Subscapularis_SuperiorHead/activation", "/forceset/Infraspinatus/activation", "/forceset/PronatorTeres/activation", "/forceset/FlexorCarpiRadialis/activation", "/forceset/Brachioradialis/activation", "/forceset/Triceps_Medial_Head/activation", "/forceset/Latissimus_Dorsi_Rostral/activation", "/forceset/Latissimus_Dorsi_Caudal/activation", "/forceset/Pectoralis_Major_Anterior/activation", "/forceset/Pectoralis_Major_Posterior/activation", "/forceset/Pectoralis_Clavicle_Head", "/forceset/Biceps_Short_Head", "/forceset/Biceps_Long_Head", "/forceset/Deltoid_Medial", "/forceset/Triceps_Lat_Head", "/forceset/Triceps_Long_Head", "/forceset/Brachialis_Proximal_Head", "/forceset/Brachialis_Distal_Head", "/forceset/Anconeus", "/forceset/Deltoid_Posterior", "/forceset/Anconeus_Short_Head", "/forceset/Subscapularis_SuperiorHead", "/forceset/Infraspinatus", "/forceset/PronatorTeres", "/forceset/FlexorCarpiRadialis", "/forceset/Brachioradialis", "/forceset/Triceps_Medial_Head", "/forceset/Latissimus_Dorsi_Rostral", "/forceset/Latissimus_Dorsi_Caudal", "/forceset/Pectoralis_Major_Anterior", "/forceset/Pectoralis_Major_Posterior"]
146+
kcolnames = ["time","paw_x","paw_y","paw_z","elbow_x","elbow_y","elbow_z"]
147+
148+
def getMu(which_sets):
149+
mu = pd.DataFrame();
150+
for set in which_sets:
151+
for file in glob.glob(base_dir+"reachset_"+str(set)+"/muscle_sol*"):
152+
tdf = pd.read_csv(file, sep= r'\t',engine='python', header=18, names=mcolnames, index_col=None)
153+
mu = pd.concat([mu,tdf], ignore_index=True)
154+
return mu
155+
156+
def getKin(which_sets):
157+
kin = pd.DataFrame();
158+
for set in which_sets:
159+
for file in glob.glob(base_dir+"reachset_"+str(set)+"/muscle_kinematics_*"):
160+
tdf = pd.read_csv(file, sep= r',|\t',engine='python', header=4, names=kcolnames,index_col=None)
161+
kin = pd.concat([kin,tdf], ignore_index=True)
162+
return kin
163+
```

0 commit comments

Comments
 (0)