diff --git a/.github/workflows/pypi_deploy.yml b/.github/workflows/pypi_deploy.yml deleted file mode 100644 index 92e4e10..0000000 --- a/.github/workflows/pypi_deploy.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Publish Python 🐍 distribution to PyPI - -on: - push: - tags: - - "v*.*.*" # run only when you push a version tag (e.g., v1.0.0) - -jobs: - build-n-publish: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.x" - - - name: Install build dependencies - run: | - python -m pip install --upgrade pip - pip install build twine - - - name: Build package - run: python -m build - - - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - with: - password: ${{ secrets.PYPI_API_KEY }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..aa0c8f9 --- /dev/null +++ b/.github/workflows/release.yml @@ -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 }} diff --git a/examples/00_quickstart_pipeline.ipynb b/examples/00_quickstart_pipeline.ipynb index 93dca75..35cbbdd 100644 --- a/examples/00_quickstart_pipeline.ipynb +++ b/examples/00_quickstart_pipeline.ipynb @@ -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": { @@ -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})\")" ] }, { @@ -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, diff --git a/pyproject.toml b/pyproject.toml index 51eed56..dcf182a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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"} @@ -87,4 +87,12 @@ where = ["."] [tool.pytest.ini_options] pythonpath = [ "." -] \ No newline at end of file +] + +[tool.semantic_release] +version_toml = [ + "pyproject.toml:project.version", +] +branch = "main" +build_command = "pip install build && python -m build" +commit_parser = "angular" \ No newline at end of file