# `Sidereon.ClockStability`
[🔗](https://github.com/neilberkman/sidereon-ex/blob/main/lib/sidereon/clock_stability.ex#L1)

Allan-family clock-stability estimators.

The functions in this module delegate to `sidereon-core`'s IEEE-1139 Allan,
modified Allan, Hadamard, and time-deviation estimators. Phase deviations are
in seconds, fractional-frequency samples are dimensionless, and averaging
times are seconds.

# `allan_error`

```elixir
@type allan_error() ::
  :empty_series
  | :invalid_tau0
  | :no_estimators
  | :empty_tau_grid
  | :invalid_averaging_factor
  | :too_few_samples
  | :non_finite_sample
  | :gap
  | :non_finite_tau
  | :non_finite_deviation
  | :invalid_options
  | :invalid_curve
  | term()
```

# `estimator`

```elixir
@type estimator() :: :adev | :overlapping_adev | :mdev | :hdev | :tdev
```

# `gap_policy`

```elixir
@type gap_policy() :: :reject | :omit_terms
```

# `power_law_noise_type`

```elixir
@type power_law_noise_type() ::
  :random_walk_fm | :flicker_fm | :white_fm | :flicker_pm | :white_pm
```

# `series`

```elixir
@type series() ::
  [number()]
  | {:phase_seconds, [number()]}
  | {:fractional_frequency, [number()]}
  | {:phase_seconds_with_gaps, [number() | nil]}
  | {:fractional_frequency_with_gaps, [number() | nil]}
```

# `tau_grid`

```elixir
@type tau_grid() :: :octave | :all | {:explicit, [pos_integer()]}
```

# `allan_deviation`

```elixir
@spec allan_deviation(series(), number(), [pos_integer()]) ::
  {:ok, Sidereon.ClockStability.Curve.t()} | {:error, allan_error()}
```

Plain non-overlapping Allan deviation for explicit averaging factors.

`tau0_s` is the base sample interval in seconds. `averaging_factors` are the
integer `m` values, so each output `tau_s` is `m * tau0_s`.

# `compute_allan_deviations`

```elixir
@spec compute_allan_deviations(series(), number(), keyword()) ::
  {:ok, Sidereon.ClockStability.Curves.t()} | {:error, allan_error()}
```

Compute a configured set of Allan-family curves.

Options:

  * `:estimators` - `:standard` for OADEV, MDEV, HDEV, and TDEV, `:all`,
    `:none`, a list of estimator atoms, or a map of estimator booleans.
  * `:tau_grid` - `:octave`, `:all`, or `{:explicit, factors}`. Averaging
    times are seconds.
  * `:gap_policy` - `:reject` or `:omit_terms` for gapped series.

# `fit_power_law_noise`

```elixir
@spec fit_power_law_noise(
  Sidereon.ClockStability.Curve.t(),
  Sidereon.ClockStability.Curve.t(),
  keyword() | Sidereon.ClockStability.PowerLawNoiseOptions.t()
) ::
  {:ok, Sidereon.ClockStability.PowerLawNoiseFit.t()} | {:error, allan_error()}
```

Identify power-law clock noise from supplied ADEV and MDEV curves.

# `hadamard_deviation`

```elixir
@spec hadamard_deviation(series(), number(), [pos_integer()]) ::
  {:ok, Sidereon.ClockStability.Curve.t()} | {:error, allan_error()}
```

Overlapping Hadamard deviation for explicit averaging factors.

`tau0_s` and returned `tau_s` values are seconds.

# `modified_adev`

```elixir
@spec modified_adev(series(), number(), [pos_integer()]) ::
  {:ok, Sidereon.ClockStability.Curve.t()} | {:error, allan_error()}
```

Modified Allan deviation for explicit averaging factors.

`tau0_s` and returned `tau_s` values are seconds.

# `overlapping_adev`

```elixir
@spec overlapping_adev(series(), number(), [pos_integer()]) ::
  {:ok, Sidereon.ClockStability.Curve.t()} | {:error, allan_error()}
```

Fully overlapping Allan deviation for explicit averaging factors.

`tau0_s` and returned `tau_s` values are seconds.

# `power_law_slope`

```elixir
@spec power_law_slope(power_law_noise_type(), :adev | :overlapping_adev | :mdev) ::
  float()
```

Return the exact Allan-family log-log slope for a power-law noise type.

# `receiver_clock_phase_deviations`

```elixir
@spec receiver_clock_phase_deviations(Sidereon.GNSS.RINEX.Observations.t()) :: [
  float() | nil
]
```

Extract RINEX receiver-clock phase deviations in seconds.

Event epochs are returned as `nil` gaps. The result can be passed as
`{:phase_seconds_with_gaps, values}` to `compute_allan_deviations/3`.

# `time_deviation`

```elixir
@spec time_deviation(series(), number(), [pos_integer()]) ::
  {:ok, Sidereon.ClockStability.Curve.t()} | {:error, allan_error()}
```

Time deviation for explicit averaging factors.

Returned deviation values are seconds.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
