Skip to content
Merged

Dev #82

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 0 additions & 32 deletions .github/workflows/pypi_deploy.yml

This file was deleted.

31 changes: 31 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Semantic Release

on:
push:
branches:
- main

jobs:
release:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Python Semantic Release
id: release
uses: python-semantic-release/python-semantic-release@v9.12.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
if: steps.release.outputs.released == 'true'
with:
password: ${{ secrets.PYPI_API_KEY }}
38 changes: 26 additions & 12 deletions examples/00_quickstart_pipeline.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,29 @@
"\n",
"Welcome to PyEyesWeb! This library is designed to extract expressive and biomechanical features from motion data in real-time.\n",
"\n",
"In this quickstart, we will build a complete, unified pipeline that extracts:\n",
"## Understanding the Architecture: Concepts vs. Implementation\n",
"\n",
"1. A Static Feature: Bounding Box Contraction (How folded/expanded is the body?)\n",
"PyEyesWeb separates **what** we measure (the conceptual framework) from **how** it is computed (the implementation API).\n",
"\n",
"2. A Dynamic Feature: Kinetic Energy (How much total energy is in the movement?)\n",
"### 1. The Conceptual Framework (What we measure)\n",
"* **Low-Level Features**: Physical biomechanics, including spatial geometry (Contraction, Expansion) and raw kinematics (Kinetic Energy, Velocity).\n",
"* **Mid-Level Features**: Qualitative, expressive aspects of movement that represent behavior or intent (e.g., Smoothness, Directness, Rhythmicity).\n",
"* **Analysis Primitives**: Domain-agnostic mathematical and statistical tools (e.g., Probability/Rarity, Signal Synchronization, Volatility) that can be applied to any data stream.\n",
"\n",
"3. An Analysis Primitive: Smoothness (How fluid is the right hand moving?)"
"### 2. The Implementation API (How we compute it)\n",
"In the code, every metric is implemented as either a **Static** or **Dynamic** feature, defined purely by its memory requirements:\n",
"* **Static Features**: Require only the instantaneous state of the *current frame*. For example, the spatial Contraction of a single pose, or instantaneous Kinetic Energy. They operate on a sliding window of size 1.\n",
"* **Dynamic Features**: Require a historical trajectory to evaluate changes *over time*. For example, checking if a movement was Smooth over the last second. They require a rolling sliding window to store past frames.\n",
"\n",
"In this quickstart, we will build a unified pipeline extracting three metrics that cross-reference these categories:\n",
"1. **Contraction** (Concept: Low-Level | API: Static Feature)\n",
"2. **Kinetic Energy** (Concept: Low-Level | API: Static Feature)\n",
"3. **Smoothness** (Concept: Low-Level | API: Dynamic Feature)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"id": "initial_id",
"metadata": {
"ExecuteTime": {
Expand All @@ -39,15 +50,18 @@
}
],
"source": [
"from utils.data_loader import load_qualisys_tsv\n",
"from utils.data_loader import load_motion_data\n",
"from utils.plot_utils import plot_feature_timeseries\n",
"\n",
"# Load data into clean 3D tensors: (Time, Joints, Dimensions)\n",
"pos_tensor, vel_tensor, _, marker_names = load_qualisys_tsv(\"data/trial0001_impulsive.tsv\")\n",
"pos_tensor, vel_tensor, acc_tensor, marker_names = load_motion_data(\"data/trial0001_impulsive.tsv\")\n",
"\n",
"# Let's track the Right Hand\n",
"hand_idx = marker_names.index(\"HAND_RIGHT\")\n",
"\n",
"N_frames, N_joints, N_dims = pos_tensor.shape\n",
"print(f\"Ready to process {N_frames} frames tracking {N_joints} joints!\")"
"print(f\"Loaded {N_frames} frames tracking {N_joints} joints.\")\n",
"print(f\"Position Tensor Shape: ({N_frames}, {N_joints}, {N_dims})\")"
]
},
{
Expand Down Expand Up @@ -186,21 +200,21 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"display_name": "pwb",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
"pygments_lexer": "ipython3",
"version": "3.12.11"
}
},
"nbformat": 4,
Expand Down
12 changes: 10 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "pyeyesweb"
version = "0.0.1a5"
version = "1.0.0b1"
requires-python = ">=3.8"
authors = [
{name = "InfoMus Lab - Casa Paganini", email = "cp.infomus@gmail.com"}
Expand Down Expand Up @@ -87,4 +87,12 @@ where = ["."]
[tool.pytest.ini_options]
pythonpath = [
"."
]
]

[tool.semantic_release]
version_toml = [
"pyproject.toml:project.version",
]
branch = "main"
build_command = "pip install build && python -m build"
commit_parser = "angular"
Loading