Library for maximum likelihood principal component analysis for AnyBody models
Project description
sillywalk
sillywalk is a Python library for statistical modeling of human motion and anthropometric data with the AnyBody Modeling System. It implements Maximum Likelihood Principal Component Analysis (ML‑PCA) to learn compact, low‑dimensional models from datasets, predict missing or individualized signals from partial inputs, and export those predictions as AnyScript include files that plug directly into AnyBody models.
Key features
- AnyBody I/O and preprocessing: Post‑process AnyBody time series and convert them to Fourier coefficients compatible with
AnyKinEqFourierDriver. - ML‑PCA modeling and prediction: Fit ML‑PCA models from tabular data, handle missing values naturally, and predict new samples from partial constraints; save/load models to and from
.npz. - AnyBody model generation: Generate templated AnyScript include files (e.g., drivers and optional human model blocks) from predicted Fourier coefficients and anthropometry.
- Friendly data interfaces: Works with pandas or polars DataFrames and NumPy arrays; installable via PyPI or pixi for reproducible workflows.
See Quick Start below for a minimal end‑to‑end example.
Installation
With pixi:
pixi workspace channel add https://repo.prefix.dev/anybody
pixi add sillywalk
or from PyPI:
pip install sillywalk
or with conda:
conda create -n sillywalk -c conda-forge -c https://repo.prefix.dev/anybody sillywalk
conda activate sillywalk
Developer Setup
This project uses pixi for dependency management and development tools.
git clone https://github.com/AnyBody-Research-Group/sillywalk
cd sillywalk
pixi install
pixi run test
See pixi documentation for more info.
Quick Start
1. Build a Model
import pandas as pd
import sillywalk
data = {
"Sex": [1, 1, 2, 2, 1, 2],
"Age": [25, 30, 28, 22, 35, 29],
"Stature": [175, 180, 165, 160, 185, 170],
"Bodyweight": [70, 80, 60, 55, 85, 65],
"Shoesize": [42, 44, 39, 38, 45, 40],
}
df = pd.DataFrame(data)
model = sillywalk.PCAPredictor(df)
2. Predict Missing Values
constraints = {"Stature": 180, "Bodyweight": 65}
result = model.predict(constraints)
3. Save and Load Models
model.export_pca_data("student_model.npz")
loaded = sillywalk.PCAPredictor.from_pca_data("student_model.npz")
prediction = loaded.predict({"Age": 24, "Shoesize": 43})
AnyBody Model Utilities
sillywalk can convert time series data to Fourier coefficients compatible with AnyBody's AnyKinEqFourierDriver:
import polars as pl
import numpy as np
import sillywalk
time = np.linspace(0, 1, 101)
hip = 30 * np.sin(2 * np.pi * time) + 10
knee = 60 * np.sin(2 * np.pi * time + np.pi/4)
df = pl.DataFrame({
'Main.HumanModel.BodyModel.Interface.Trunk.PelvisThoraxExtension': hip,
'Main.HumanModel.BodyModel.Interface.Right.KneeFlexion': knee,
})
fourier_df = sillywalk.anybody.compute_fourier_coefficients(df, n_modes=6)
print(fourier_df)
Each time series column is decomposed into Fourier coefficients (_a0 to _a5, _b1 to _b5).
┌────────────┬────────────┬───────────┬───┬───────────┬───────────┬───────────┐
│ ...tension ┆ ...tension ┆ ...tensio ┆ … ┆ ...Flexio ┆ ...Flexio ┆ ...Flexio │
│ _a0 ┆ _a1 ┆ n_a2 ┆ ┆ n_b3 ┆ n_b4 ┆ n_b5 │
│ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- │
│ f64 ┆ f64 ┆ f64 ┆ ┆ f64 ┆ f64 ┆ f64 │
╞════════════╪════════════╪═══════════╪═══╪═══════════╪═══════════╪═══════════╡
│ 10.0 ┆ 0.928198 ┆ -0.021042 ┆ … ┆ -0.550711 ┆ -0.218252 ┆ -0.169925 │
└────────────┴────────────┴───────────┴───┴───────────┴───────────┴───────────┘
Generate AnyBody Include Files
You can generate AnyScript include files from a dictionary or DataFrame with Fourier coefficients and anthropometric data:
sillywalk.anybody.write_anyscript(
predicted_data,
targetfile="predicted_motion.any"
)
This creates AnyKinEqFourierDriver entries for use in AnyBody models.
Example: Complete Human Model
sillywalk.anybody.write_anyscript(
predicted_data,
targetfile="complete_human_model.any",
create_human_model=True
)
PCAPredictor
PCAPredictor selects numeric columns with sufficient variance and fits a PCA model. It can:
- Predict all columns from partial constraints on PCA columns using a KKT least‑squares system.
- Convert between primal parameters and principal components.
- Persist models to
.npzfiles.
Notes
- Constraints on columns excluded from PCA are not allowed and raise ValueError.
- If no constraints are provided,
predictreturns the column means. - If no columns pass variance screening, the model has zero components and
predictreturns means.
Example
import pandas as pd
from sillywalk import PCAPredictor
df = pd.DataFrame({
"a": [1, 2, 3, 4],
"b": [2, 2.5, 3, 3.5],
"c": [10, 10, 10, 10], # excluded (zero variance)
})
model = PCAPredictor(df)
pred = model.predict({"a": 3.2})
pcs = model.parameters_to_components({k: pred[k] for k in model.pca_columns})
back = model.components_to_parameters(pcs)
License
MIT License. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sillywalk-1.0.0a4.tar.gz.
File metadata
- Download URL: sillywalk-1.0.0a4.tar.gz
- Upload date:
- Size: 12.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49542720a053791b5522fd3f6b986f912fc9b3f647565097696d19ce3348799c
|
|
| MD5 |
0faf86acdbb635ce9b0af873f6738402
|
|
| BLAKE2b-256 |
2c772a29adabc8c9d11cb6b9c66f7e4cdd353f8ebd42408af85b99f925ac4b16
|
Provenance
The following attestation bundles were made for sillywalk-1.0.0a4.tar.gz:
Publisher:
build.yml on AnyBody-Research-Group/sillywalk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sillywalk-1.0.0a4.tar.gz -
Subject digest:
49542720a053791b5522fd3f6b986f912fc9b3f647565097696d19ce3348799c - Sigstore transparency entry: 412077800
- Sigstore integration time:
-
Permalink:
AnyBody-Research-Group/sillywalk@4fbea48610ad7c06c74a0d29c6b7b8e4a3f7d1ab -
Branch / Tag:
refs/tags/1.0.0a4 - Owner: https://github.com/AnyBody-Research-Group
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@4fbea48610ad7c06c74a0d29c6b7b8e4a3f7d1ab -
Trigger Event:
push
-
Statement type:
File details
Details for the file sillywalk-1.0.0a4-py3-none-any.whl.
File metadata
- Download URL: sillywalk-1.0.0a4-py3-none-any.whl
- Upload date:
- Size: 14.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f442dab60310a9f948c744676c8f2e7bbe2fb31dd4f3016174057149fd1db476
|
|
| MD5 |
3e978a1df9141ee949afe0782ede6227
|
|
| BLAKE2b-256 |
1238f7af9e85d9f71a2cd852865ec0ec0bc8ff0b66de19a742e5c336453fa0e5
|
Provenance
The following attestation bundles were made for sillywalk-1.0.0a4-py3-none-any.whl:
Publisher:
build.yml on AnyBody-Research-Group/sillywalk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sillywalk-1.0.0a4-py3-none-any.whl -
Subject digest:
f442dab60310a9f948c744676c8f2e7bbe2fb31dd4f3016174057149fd1db476 - Sigstore transparency entry: 412077809
- Sigstore integration time:
-
Permalink:
AnyBody-Research-Group/sillywalk@4fbea48610ad7c06c74a0d29c6b7b8e4a3f7d1ab -
Branch / Tag:
refs/tags/1.0.0a4 - Owner: https://github.com/AnyBody-Research-Group
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@4fbea48610ad7c06c74a0d29c6b7b8e4a3f7d1ab -
Trigger Event:
push
-
Statement type: