# `Sidereon.GNSS.PreciseEphemeris.StateBatch`
[🔗](https://github.com/neilberkman/sidereon-ex/blob/main/lib/sidereon/gnss/precise_ephemeris/state_batch.ex#L1)

Contiguous satellite-state arrays returned by a batched ephemeris query.

The positions are ITRF/IGS ECEF metres and clocks are seconds. Element `i` of
every field belongs to the same input satellite/epoch pair:

  * `:positions_ecef_m` - `{x_m, y_m, z_m}` tuples. Failed elements carry the
    sentinel returned by `missing_position_ecef_m/0`.
  * `:clocks_s` - satellite clock offsets in seconds, or `nil`.
  * `:statuses` - `:valid`, `:gap`, or `:error`.
  * `:results` - `:ok` or `{:error, reason}` with the core scalar reason.

A `:gap` is a data gap such as an unknown satellite or an out-of-coverage
epoch. Other failures are marked `:error`.

# `element_result`

```elixir
@type element_result() :: :ok | {:error, term()}
```

# `position_component`

```elixir
@type position_component() :: float() | :nan
```

# `status`

```elixir
@type status() :: :valid | :gap | :error
```

# `t`

```elixir
@type t() :: %Sidereon.GNSS.PreciseEphemeris.StateBatch{
  clocks_s: [float() | nil],
  positions_ecef_m: [vec3()],
  results: [element_result()],
  statuses: [status()]
}
```

# `vec3`

```elixir
@type vec3() :: {position_component(), position_component(), position_component()}
```

# `count`

```elixir
@spec count(t()) :: non_neg_integer()
```

Number of elements in the batch.

# `element`

```elixir
@spec element(t(), non_neg_integer()) ::
  {:ok, %{position_ecef_m: vec3(), clock_s: float() | nil}} | {:error, term()}
```

Reconstruct one element as `{:ok, %{position_ecef_m, clock_s}}` or an error.

Indexing is zero-based to match the core batch element contract. Returns
`{:error, :out_of_range}` when `index` is outside the batch.

# `missing_position_ecef_m`

```elixir
@spec missing_position_ecef_m() :: vec3()
```

Position sentinel used when an element has no valid state.

The core sentinel is a NaN vector. BEAM NIFs cannot transport NaN floats, so
this binding represents it as `{:nan, :nan, :nan}`. Check `results` or
`statuses` before using a position row.

---

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