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

# Measurement scales

> Understand the scale boundaries, scoring ranges, and how to display biomechanical gauges for each measurement.

When rendering a gauge or scale for biomechanical measurements, you need to know the
**overall min/max boundaries** of the scale in addition to the `range_good` and `range_okay`
values returned by the API.

This guide documents the fixed scale boundaries for every measurement type so you can
render consistent visualizations regardless of the runner's measured value.

## How scoring ranges work

Each biomechanical measurement in the API response includes:

| Field            | Description                                                         |
| ---------------- | ------------------------------------------------------------------- |
| `measured_value` | The actual measured angle (in degrees)                              |
| `score_number`   | Normalized score between 0 and 1                                    |
| `range_good`     | `[min, max]` — values within this range score highest               |
| `range_okay`     | `[min, max]` — values within this range score moderately            |
| `range_bad`      | `[min, max]` — (back view only) values outside okay, scoring lowest |

<Info>
  All range values are expressed in **degrees**. Range boundaries can overlap — see
  [analysis workflow](/guides/analysis-workflow) for inclusion/exclusion rules.
</Info>

## Back view — fixed scale boundaries

Back-view measurements use **fixed ranges** that do not change based on athlete morphology.
The API returns `range_bad` for back-view segments — use it as the overall scale boundary.

### Pelvic drop (per side)

| Field         | Value    | Unit    |
| ------------- | -------- | ------- |
| `range_good`  | `[0, 2]` | degrees |
| `range_okay`  | `[2, 4]` | degrees |
| `range_bad`   | `[4, 8]` | degrees |
| **Scale min** | **0**    | degrees |
| **Scale max** | **8**    | degrees |

<Tip>
  `range_bad[1]` (8°) is the scale maximum. Display the gauge from 0 to 8.
</Tip>

### Pronation / supination (per side)

| Field         | Value       | Unit    |
| ------------- | ----------- | ------- |
| `range_good`  | `[-5, 5]`   | degrees |
| `range_okay`  | `[-10, 10]` | degrees |
| `range_bad`   | `[-20, 20]` | degrees |
| **Scale min** | **-20**     | degrees |
| **Scale max** | **20**      | degrees |

Negative values indicate pronation (foot rolling inward), positive values indicate
supination (foot rolling outward).

### Knee adduction (per side)

| Field         | Value       | Unit    |
| ------------- | ----------- | ------- |
| `range_good`  | `[-3, 3]`   | degrees |
| `range_okay`  | `[-5, 5]`   | degrees |
| `range_bad`   | `[-10, 10]` | degrees |
| **Scale min** | **-10**     | degrees |
| **Scale max** | **10**      | degrees |

Negative values indicate adduction (knee inward), positive values indicate abduction
(knee outward).

### Back view summary

```
Pelvic drop:       |====GOOD====|==OKAY==|=====BAD=====|
                   0           2        4             8

Pronation:    |===BAD===|==OK==|===GOOD===|==OK==|===BAD===|
             -20      -10     -5         5      10        20

Knee add.:    |===BAD===|=OK=|==GOOD==|=OK=|===BAD===|
             -10       -5   -3       3    5        10
```

## Side view — personalized scale boundaries

Side-view ranges are **personalized** based on the runner's height, weight, and pace.
The `range_good` and `range_okay` values returned by the API vary between analyses.

<Warning>
  The API does not return `range_bad` for side-view measurements. Use the recommended
  display ranges below to render consistent gauges.
</Warning>

### Recommended display ranges

Use these fixed boundaries when rendering side-view gauges. They accommodate the full
range of personalized values the API can return:

| Measurement           | Scale min            | Scale max            | Unit        | Notes                                          |
| --------------------- | -------------------- | -------------------- | ----------- | ---------------------------------------------- |
| **Head**              | `range_okay[0] - 10` | `range_okay[1] + 10` | degrees     | Negative = looking down, positive = looking up |
| **Trunk (back)**      | `range_okay[0] - 10` | `range_okay[1] + 10` | degrees     | Forward lean angle                             |
| **Arm**               | `range_okay[0] - 10` | `range_okay[1] + 10` | degrees     | Elbow angle                                    |
| **Front knee**        | `range_okay[0] - 10` | `180`                | degrees     | Knee extension at foot landing                 |
| **Back knee**         | `0`                  | `range_okay[1] + 10` | degrees     | Knee flexion (heel kick)                       |
| **Foot (overstride)** | `-10`                | `20`                 | degrees / % | Overstride angle relative to center of gravity |

<Tip>
  The formula `range_okay[0] - 10` / `range_okay[1] + 10` provides a safe margin around
  any measured value while keeping the scale readable.
</Tip>

### Foot / overstride (fixed)

Unlike other side-view segments, foot/overstride uses **fixed ranges** regardless of
athlete morphology:

<Tabs>
  <Tab title="Overground">
    | Field         | Value      |
    | ------------- | ---------- |
    | `range_good`  | `[-10, 5]` |
    | `range_okay`  | `[5, 10]`  |
    | **Scale min** | **-10**    |
    | **Scale max** | **20**     |
  </Tab>

  <Tab title="Treadmill">
    | Field         | Value       |
    | ------------- | ----------- |
    | `range_good`  | `[-10, 10]` |
    | `range_okay`  | `[10, 20]`  |
    | **Scale min** | **-10**     |
    | **Scale max** | **30**      |
  </Tab>
</Tabs>

Negative values mean the foot lands behind the center of gravity (good). Positive values
indicate overstride (foot landing ahead of the center of gravity).

### Side view — typical range examples

These are examples of actual API responses for a 1.75m / 70kg runner at 5:00 min/km pace:

| Measurement | `range_good` | `range_okay` | Recommended scale |
| ----------- | ------------ | ------------ | ----------------- |
| Head        | `[-14, -4]`  | `[-18, 0]`   | `[-28, 10]`       |
| Trunk       | `[6, 12]`    | `[2, 16]`    | `[-8, 26]`        |
| Arm         | `[75, 85]`   | `[71, 89]`   | `[61, 99]`        |
| Front knee  | `[145, 180]` | `[136, 145]` | `[126, 180]`      |
| Back knee   | `[0, 97]`    | `[97, 106]`  | `[0, 116]`        |
| Foot        | `[-10, 5]`   | `[5, 10]`    | `[-10, 20]`       |

<Info>
  Side-view ranges change with athlete morphology. The values above are illustrative —
  always compute your scale boundaries from the actual `range_okay` values returned per analysis.
</Info>

## Implementation example

```javascript theme={null}
function getScaleBounds(segment, analysisType) {
  // Back view: use range_bad directly
  if (analysisType === 'back_view') {
    return {
      min: segment.range_bad[0],
      max: segment.range_bad[1],
    };
  }

  // Side view foot: fixed scale
  if (segment.texts?.search_key?.startsWith('Midfoot') ||
      segment.texts?.search_key?.startsWith('Rearfoot') ||
      segment.texts?.search_key?.startsWith('Forefoot')) {
    return { min: -10, max: 20 };
  }

  // Side view forward_cycle: lower bound from range_okay, upper bound is 180
  if (segment.texts?.title === 'Front knee angle at foot landing') {
    return {
      min: segment.range_okay[0] - 10,
      max: 180,
    };
  }

  // Side view back_cycle: lower bound is 0, upper bound from range_okay
  if (segment.texts?.title === 'Back knee angle at foot landing') {
    return {
      min: 0,
      max: segment.range_okay[1] + 10,
    };
  }

  // Side view head, trunk, arm: ±10 from range_okay
  return {
    min: segment.range_okay[0] - 10,
    max: segment.range_okay[1] + 10,
  };
}
```

## Score interpretation

The `score_number` field (0 to 1) indicates how well the measured value falls within
the ideal range:

| Score range | Interpretation                           |
| ----------- | ---------------------------------------- |
| 0.7 — 1.0   | Good — within or very near `range_good`  |
| 0.4 — 0.7   | Okay — within `range_okay`               |
| 0.0 — 0.4   | Needs improvement — outside `range_okay` |

The overall `total_score` for side view is a **weighted** combination of segment scores,
not a simple average.
