> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/opentrack/opentrack/llms.txt
> Use this file to discover all available pages before exploring further.

# Alpha Spectrum Filter

> Advanced adaptive filter with multi-head composition, motion prediction, and Rényi-MTM probability framework

The Alpha Spectrum filter is OpenTrack's most sophisticated filtering algorithm. It adapts smoothing strength from recent motion energy per axis and includes multiple "heads" (EMA, Brownian, Adaptive, Predictive) composed using a Rényi-Tsallis probability framework.

<Note>
  This filter is designed for advanced users who want maximum control and are willing to tune parameters. For most users, the **Simplified Mode** with default settings provides excellent results.
</Note>

## How It Works

The Alpha Spectrum filter uses an adaptive EMA (Exponentially Weighted Moving Average) update:

```cpp theme={null}
output += alpha * (input - output)
alpha = min + (max - min) * motion^curve
```

Where `motion` is a normalized innovation-energy estimate in `[0, 1]`:

* **Low motion** → alpha stays near Min (more smoothing, less jitter)
* **High motion** → alpha moves toward Max (faster response)

### Multi-Head Composition

The filter implements a **Hydra-style 4-head architecture**:

1. **EMA head**: Standard exponential smoothing
2. **Brownian head**: Noise-energy contribution
3. **Adaptive head**: Sustained-motion responsiveness boost (15% higher activation threshold)
4. **Predictive head**: One-step-ahead prediction from previous frame

These heads are scored by generalized likelihood using Rényi/Tsallis neck scoring, then composed using MTM (Multiple Model) shoulder weighting.

```mermaid theme={null}
graph TB
    A[Raw Input] --> B[EMA Head]
    A --> C[Brownian Head]
    A --> D[Adaptive Head]
    A --> E[Predictive Head]
    B --> F[Rényi Neck Scoring]
    C --> F
    D --> F
    E --> F
    F --> G[MTM Shoulder Composition]
    G --> H[Filtered Output]
```

<Warning>
  The filter is currently in **Phase A** implementation. Full transition-matrix MTM with explicit regime semantics is not yet implemented.
</Warning>

## Parameters

### Simplified Mode (Recommended)

The default workflow uses simplified controls at the top of the dialog:

<ParamField path="adaptive" type="boolean" default="false">
  Enable motion-history responsiveness boost during sustained movement.

  * **Enabled**: Adds adaptive boosting for fast gameplay
  * **Disabled**: Uses only base Min/Max/Curve mapping for predictable feel
</ParamField>

<ParamField path="advanced" type="boolean" default="false">
  Show detailed per-parameter controls. When off, detailed controls are disabled (greyed out).
</ParamField>

<ParamField path="ema_minmax_range" type="slider" default="[0.085, 0.218]">
  Controls both rotation and translation Min/Max together.

  * **Min range**: 0.5% to 40% (0.005 to 0.4)
  * **Max range**: 2% to 100% (0.02 to 1.0)
</ParamField>

<ParamField path="curve_deadzone_coupling" type="slider" default="[4.26, 0.156, 1.041]">
  Controls all four curve/deadzone parameters together:

  * Rotation Curve (0.2 to 8.0)
  * Translation Curve (0.2 to 8.0)
  * Rotation Deadzone (0.0° to 0.3°)
  * Translation Deadzone (0.0 to 2.0 mm)
</ParamField>

### Core EMA Controls

<AccordionGroup>
  <Accordion title="Rotation Parameters">
    <ParamField path="rotation_min" type="float" default="0.085" range="[0.005, 0.4]">
      Minimum alpha for rotations. Higher = less lag at rest but more jitter.
    </ParamField>

    <ParamField path="rotation_max" type="float" default="0.218" range="[0.02, 1.0]">
      Maximum alpha for rotations. Higher = snappier turns and faster catch-up.
    </ParamField>

    <ParamField path="rotation_curve" type="float" default="4.26" range="[0.2, 8.0]">
      Shape of alpha transition based on motion:

      * Higher (>1): keeps heavy smoothing longer, opens up late
      * Lower (\<1): opens up earlier, more immediate feel
    </ParamField>

    <ParamField path="rotation_deadzone" type="float" default="0.156" range="[0.0, 0.3]" unit="degrees">
      Suppresses tiny rotational deltas before adaptation. Too high makes small movements feel ignored.
    </ParamField>
  </Accordion>

  <Accordion title="Translation Parameters">
    <ParamField path="translation_min" type="float" default="0.085" range="[0.005, 0.4]">
      Minimum alpha for X/Y/Z position. Higher = less lag but more shake.
    </ParamField>

    <ParamField path="translation_max" type="float" default="0.218" range="[0.02, 1.0]">
      Maximum alpha for X/Y/Z position. Higher = faster positional response.
    </ParamField>

    <ParamField path="translation_curve" type="float" default="4.26" range="[0.2, 8.0]">
      Shape of alpha transition for translation. Same behavior as rotation curve.
    </ParamField>

    <ParamField path="translation_deadzone" type="float" default="1.041" range="[0.0, 2.0]" unit="mm">
      Suppresses tiny translational jitter. Too high creates a sticky center feel.
    </ParamField>
  </Accordion>
</AccordionGroup>

### Advanced Hydra/NGC Controls

<Note>
  These controls appear in the left column when **Advanced Mode** is enabled. Start with defaults and tune only if needed.
</Note>

<ParamField path="brownian_head_gain" type="float">
  Scales Brownian head drive before alpha synthesis. Controls how much noise-energy contributes to adaptive response.
</ParamField>

<ParamField path="adaptive_threshold_lift" type="float">
  Raises the activation threshold for the Adaptive head. Higher = Adaptive head engages later during stronger motion.
</ParamField>

<ParamField path="predictive_head_gain" type="float">
  Scales influence of cached next-frame prediction. Watch **Predictive error (rot/pos)** status to tune.
</ParamField>

<ParamField path="mtm_shoulder_base" type="float">
  Sets minimum shoulder trust level before mode-dependent lift. Controls overall trust in MTM composition.
</ParamField>

<ParamField path="ngc_kappa" type="float">
  Controls depth-scale commutator coupling strength. Affects how Z-depth influences translational likelihood.
</ParamField>

<ParamField path="ngc_nominal_z" type="float">
  Reference distance used by NGC coupling term. Nominal Z-depth for depth-scale normalization.
</ParamField>

### Component Toggles

In Advanced Mode, you can enable/disable individual filter components:

<ParamField path="enable_ema" type="boolean" default="true">
  **EMA smoothing head**

  * **On**: Uses `output += alpha * (input - output)`
  * **Off**: Pure pass-through (`output = input`) while status info still updates
</ParamField>

<ParamField path="enable_brownian" type="boolean" default="true">
  **Brownian interface contribution**

  * **On**: Brownian term contributes to both adaptive drive and MTM measurement
  * **Off**: Brownian status info computes, but contribution is disabled
</ParamField>

<ParamField path="enable_mtm" type="boolean" default="true">
  **Rényi MTM shoulder composition**

  * **On**: Mode diffusion + posterior update influence adaptive responsiveness
  * **Off**: MTM influence is fully removed (`mode_e` does not affect response)
</ParamField>

## Tuning Workflow

<Steps>
  <Step title="Start with Adaptive Mode off">
    Disable Adaptive Mode initially. Enable it only if you need extra responsiveness during sustained motion.
  </Step>

  <Step title="Observe status info">
    Watch the status line while moving and while still to understand current behavior.

    ```text theme={null}
    Mon|E1 B1 A1 P1 M1|rE0.350 rP0.350 pE0.534 pP0.500 k0.000
    ```

    Legend:

    * `Mon`: Status active
    * `E/B/A/P/M`: EMA, Brownian, Adaptive, Predictive, MTM toggles
    * `rE`, `rP`: Rotation mode expectation and peak
    * `pE`, `pP`: Translation mode expectation and peak
    * `k`: Live NGC coupling residual
  </Step>

  <Step title="Tune rotation first, then translation">
    Adjust one family at a time to avoid chasing parameter interactions.
  </Step>

  <Step title="Fine-tune specific parameters">
    Make small moves (\~5-10% of slider range) and test with:

    * Still head pose (jitter check)
    * Slow pan
    * Fast snap turn
    * Lean in/out
  </Step>
</Steps>

### Two-Column Advanced Tuning

When **Advanced Mode** is enabled, use this order:

<Tabs>
  <Tab title="Left Column (Hydra/NGC)">
    1. Start with defaults
    2. Tune **MTM Shoulder Base** for overall trust level
    3. Tune **Brownian Head Gain** to balance jitter vs response
    4. Tune **Adaptive Threshold Lift** to control adaptive engagement
    5. Tune **Predictive Head Gain** while watching predictive error status
    6. Tune **NGC Kappa** and **NGC Nominal Z** last for translational coupling
  </Tab>

  <Tab title="Right Column (Core EMA)">
    1. Set rotation Min/Max/Curve/Deadzone for desired rotational feel
    2. Set translation Min/Max/Curve/Deadzone for positional feel
    3. Test with all movement types
  </Tab>
</Tabs>

<Warning>
  If tuning regresses performance, use **Reset sliders to defaults** and repeat the process. The reset button writes default values to the active profile immediately.
</Warning>

## Recommended Profiles

### Stable / Simulator Focus

Maximum smoothness for precision work:

```yaml theme={null}
rotation_min: 0.03
rotation_max: 0.55
rotation_curve: 1.8
rotation_deadzone: 0.04

translation_min: 0.04
translation_max: 0.65
translation_curve: 1.5
translation_deadzone: 0.12

adaptive_mode: false
```

### Balanced (Factory Default)

General purpose balanced settings:

```yaml theme={null}
rotation_min: 0.085
rotation_max: 0.218
rotation_curve: 4.26
rotation_deadzone: 0.156

translation_min: 0.085
translation_max: 0.218
translation_curve: 4.26
translation_deadzone: 1.041

adaptive_mode: false
```

### Responsive / Fast Action

Minimal lag for competitive gaming:

```yaml theme={null}
rotation_min: 0.06
rotation_max: 0.85
rotation_curve: 0.9
rotation_deadzone: 0.02

translation_min: 0.07
translation_max: 0.90
translation_curve: 0.8
translation_deadzone: 0.06

adaptive_mode: true
```

## Status Information

The status line uses a compact fixed-width format to avoid UI resizing:

<CodeGroup>
  ```text Status Line Format theme={null}
  Mon|E1 B1 A1 P1 M1|rE0.350 rP0.350 pE0.534 pP0.500 k0.000
  ```

  ```text Brownian Status theme={null}
  raw: 0.042  filtered: 0.038  delta: 0.004  damped: 0.002
  ```

  ```text Contribution Status theme={null}
  EMA: 0.45  Brownian: 0.15  Adaptive: 0.25  Predictive: 0.10  MTM: 0.05
  ```
</CodeGroup>

**Status fields:**

* `Mon`: Monitoring active
* `E/B/A/P/M`: Head toggles (1=enabled, 0=disabled)
* `rE/rP`: Rotation mode expectation/peak
* `pE/pP`: Translation mode expectation/peak
* `k`: NGC coupling residual

**Brownian status:**

* `raw`: Instantaneous noise energy
* `filtered`: Smoothed noise energy
* `delta`: Difference (raw - filtered)
* `damped`: Damped contribution

## Troubleshooting

<AccordionGroup>
  <Accordion title="View jitters while still">
    * Increase Min smoothing or deadzone
    * Check Brownian damped status info
    * Reduce Brownian Head Gain
  </Accordion>

  <Accordion title="Feels laggy during turns">
    * Raise Max smoothing
    * Lower Curve value
    * Enable Adaptive Mode
    * Increase Adaptive Threshold Lift
  </Accordion>

  <Accordion title="Feels too twitchy">
    * Lower Max smoothing
    * Raise Curve value
    * Disable Adaptive Mode
  </Accordion>

  <Accordion title="Small intentional movement ignored">
    * Reduce deadzone values
    * Check that motion exceeds deadzone threshold
  </Accordion>
</AccordionGroup>

## Implementation Notes

<Note>
  **Rotation wrap-around** is handled automatically. Angles crossing ±180° are properly unwrapped.

  **Recenter** resets internal state on the next frame, clearing history and mode probabilities.
</Note>

### Code References

Relevant source files in the OpenTrack codebase:

* Core filter/update: `filter-alpha-spectrum/ftnoir_filter_alpha_spectrum.cpp`
* State definitions: `filter-alpha-spectrum/ftnoir_filter_alpha_spectrum.h`
* Dialog UI: `filter-alpha-spectrum/ftnoir_filter_alpha_spectrum_dialog.cpp`

### Implementation Status

**Currently implemented:**

* Per-axis adaptive EMA smoothing
* Hydra-style four-head composition (EMA + Brownian + Adaptive + Predictive)
* True Rényi/Tsallis neck scoring across enabled heads
* MTM shoulder composition over neck-normalized head candidates
* NGC depth-scale commutator coupling term
* Alpha-spectrum mode probability vector (7 bins) with per-frame diffusion
* Measurement-driven mode likelihood updates and normalized posterior
* Runtime status info in settings dialog

**Not yet implemented:**

* Full transition-matrix MTM with explicit regime semantics
* Rényi-distance likelihood over expanded head sets
* IMM-style mode mixing across explicit motion regimes

## Further Reading

<Card title="Author Discussion" icon="github" href="https://github.com/ganzuul/ancg_spectrum/blob/main/README.md">
  Technical deep-dive and research background for the Alpha Spectrum filter implementation
</Card>
