The Problem

Freemocap is a motion capture system with a complex interdependent codebase where circular imports span three modules in the path-and-filenames subsystem, and a 1,728-line calibration file creates a single point of failure for any change involving camera setup. The project's entry points touch 132+ functions each, meaning a modification to calibration or recording flow ripples across the entire system.

What This Does

The repository contains three sub-projects: freemocap (176 files, the core package), experimental (91 files, including a React UI and benchmarks), and ipython_jupyter_notebooks (4 notebooks). Primary frameworks are React, Flask, FastAPI, OpenCV, and YOLO, with Python (179 files) and TypeScript/TSX (44 files) as the dominant languages. The package is installable via pip install -e . from a pyproject.toml and launches through python -m freemocap or the freemocap CLI script.

Execution starts at two entry points: main in freemocap/__main__.py:15 reaches 132 functions, and run in freemocap/diagnostics/calibration/calculate_calibration_diagnostics.py:12 reaches 101 functions. The internal call graph shows 831 resolved call edges. The most connected module is freemocap/gui/qt/main_window/freemocap_main_window (Ca 1, Ce 33, instability 0.97), and the deepest nesting reaches 17 levels in freemocap/core_processes/capture_volume_calibration/anipose_camera_calibration/freemocap_anipose.py. Circular imports affect freemocap/system/paths_and_filenames/file_and_folder_names.py, freemocap/system/paths_and_filenames/path_getters.py, and freemocap/gui/qt/utilities/save_and_load_gui_state.py. The system touches the filesystem via 23 functions, runs 6 external commands, and makes 3 outbound network calls (through freemocap/utilities/download_sample_data.py).

Key files by responsibility:

  • freemocap/core_processes/capture_volume_calibration/anipose_camera_calibration/freemocap_anipose.py – 112 functions, 4 classes; defines triangulate_simple, get_error_dict, check_errors, resample_points_extra
  • freemocap/system/paths_and_filenames/path_getters.py – 32 functions; defines os_independent_home_dir, get_log_file_path, create_camera_calibration_file_name, get_freemocap_data_folder_path; called from 23 files; reads/writes files
  • freemocap/data_layer/recording_models/recording_info_model.py – 38 functions, 2 classes; defines __init__, active_tracker, file_prefix, path; called from 9 files, calls into 7
  • freemocap/gui/qt/main_window/freemocap_main_window.py – 31 functions, 1 class; defines __init__, _create_tools_dock_widget, _handle_videos_saved_to_this_folder_signal, _handle_processing_finished_signal, handle_start_new_session_action; called from 2 files, calls into 30, reads/writes files
  • freemocap/data_layer/data_saver/data_models.py – 6 functions, 8 classes; defines check_weights, __init__, dict, tracked_point_names, timestamp; called from 9 files

How It Is Wired

Execution flows from main → qt_gui_main → get_freemocap_data_folder_path [filesystem via freemocap_data_folder_path.mkdir], or from run → save_dictionary_to_json [filesystem via json_file_path.write_text]. The path-and-filenames subsystem forms a cycle: file_and_folder_names.py ←→ path_getters.py ←→ save_and_load_gui_state.py, meaning any import change in one propagates to the others. The freemocap_main_window widget orchestrates session start/stop, video handling, and signal callbacks, while recording_info_model owns per-session state (active_tracker, file_prefix, path). Calibration work funnels through freemocap_anipose.py, which is called from 8 other files and itself contains the deepest nesting and broadest exception handling. The UI service layer (experimental/react_fastapi/) provides FastAPI endpoints for camera detection and WebSocket frame streaming, but the core processing pipeline (freemocap/core_processes/process_motion_capture_videos/) handles YOLO-based video tracking, folder-level recording, and headless processing. Duplicated 6-line blocks appear in 12 files across the benchmark and process modules, indicating shared logic that could be extracted into helpers.

How To Use It

Setup: Create a Python 3.10–3.12 environment (3.11 recommended) and install the package in editable mode:

conda create -n freemocap-env python=3.11
conda activate freemocap-env
git clone https://github.com/moses-y/freemocap
cd freemocap
pip install -e .

Configuration: No environment variables or secret keys are required for basic operation. The freemocap/system/paths_and_filenames/path_getters.py module resolves data-folder paths at runtime. The freemocap/utilities/download_sample_data.py makes outbound network calls if sample datasets are needed.

Running it: Launch the GUI:

python -m freemocap

or use the CLI script freemocap after installation. For headless processing of a recording folder:

python -m freemocap --headless <folder_path>

Real-World Use

A research team needing to process video recordings of marker-based motion capture can clone the repo, install in a conda environment, and use the GUI to select video folders. The system auto-detects cameras via YOLO/OpenCV, runs triangulation through freemocap_anipose.py, and saves skeleton data as NumPy arrays. For automated pipelines, the headless entry point processes folders without UI interaction, outputting calibrated 3D data ready for downstream analysis. The process_recording_folder function handles event-driven cancellation via KillEventException, enabling integration into scheduled jobs.

Code Health & Issues

  • HIGH/soundness – 7 modules in circular imports across file_and_folder_names.py, path_getters.py, and save_and_load_gui_state.py; break the cycle by extracting shared types or deferring imports.
  • HIGH/cognitive_load – freemocap/core_processes/capture_volume_calibration/anipose_camera_calibration/freemocap_anipose.py is 1,728 lines with max indentation depth 17; split into cohesive units by responsibility.
  • HIGH/cognitive_load – 21 files have deep nesting; flatten with early returns/guard clauses and extract inner blocks.
  • MEDIUM/clarity – 5 hub modules with 23+ dependents each (file_and_folder_names.py, path_getters.py, post_processing_parameter_models.py); keep stable and small, move volatile logic out.
  • MEDIUM/resilience – 6 files have broad except clauses that swallow errors indiscriminately; catch specific exceptions and re-raise or log the rest.
  • MEDIUM – GITHUB_TOKEN permissions not declared least-privilege in .github/workflows/coverage-testing.yml; add permissions: contents: read.
  • MEDIUM – Test suite covers 10 files against 224 source files (ratio 0.045); add tests for highest fan-in modules first.
  • LOW – 3 stale TODO/FIXME markers across split_and_save.py, process_motion_capture_data_panel.py, and path_getters.py; triage or resolve.

The Bottom Line

Freemocap is a functional, well-structured motion capture system with a capable GUI and headless pipeline, but its circular imports, outsized calibration module, and sparse test coverage mean changes to core flow require careful ripple analysis. It's suitable for research teams willing to invest in understanding the dependency graph, but not for teams needing rapid, safe iteration on calibration or recording logic without risk of hidden breakage.