# `Quiddity.Recognition`
[🔗](https://github.com/d-led/ex.quiddity/blob/main/lib/quiddity/recognition.ex#L1)

What quiddity recognised in a part: its features, and what every face is.

This is quiddity's own `recognition/6` document, read rather than reshaped,
with three questions answered once at the door because everything downstream
asks them:

  * `by_family/1` — the records grouped under the family that found them;
  * `owner/2` — which feature a given face belongs to, which is what turns a
    point a sensor landed on into a named feature;
  * every face accounted for — a face is part of a feature, part of the body
    (with the reason), refused, or unexplained. A file that reads without
    errors is not a promise every feature was found, and the unexplained faces
    are where that promise is kept honest.

# `face_owner`

```elixir
@type face_owner() :: String.t() | :body | :refused | :unexplained | :unaccounted
```

# `t`

```elixir
@type t() :: %Quiddity.Recognition{
  by_family: %{optional(String.t()) =&gt; [map()]},
  coordinate_space: String.t(),
  face_count: non_neg_integer(),
  face_owner: %{optional(non_neg_integer()) =&gt; face_owner()},
  failures: [map()],
  frame: map(),
  input_repairs: [String.t()],
  package: map(),
  records: [map()],
  run_mode: String.t(),
  schema_version: String.t(),
  source_sha256: String.t() | nil
}
```

# `by_family`

```elixir
@spec by_family(t(), String.t()) :: [map()]
```

The records a family found, and `[]` for a family that found none.

# `families`

```elixir
@spec families(t()) :: [{String.t(), non_neg_integer()}]
```

The families with records, and how many each found, biggest first.

# `family_of`

```elixir
@spec family_of(t(), non_neg_integer()) :: String.t() | nil
```

The family a face's feature belongs to, or `nil` when no feature owns it.

This is the question a sensel asks: "what am I on?"

# `owner`

```elixir
@spec owner(t(), non_neg_integer()) :: face_owner()
```

What a face is: the id of the feature it belongs to, `:body`, `:refused`, or
`:unexplained`.

# `parse`

```elixir
@spec parse(map()) :: t()
```

Reads a recognition document, as the engine wrote it.

# `record`

```elixir
@spec record(t(), String.t()) :: map() | nil
```

A record by its id (`"holes/0"`), or `nil`.

# `records`

```elixir
@spec records(t()) :: [map()]
```

Every record, in the order the families are documented.

# `unexplained_faces`

```elixir
@spec unexplained_faces(t()) :: [non_neg_integer()]
```

The faces no feature claims and nothing else explains.

# `unproved`

```elixir
@spec unproved(t()) :: [map()]
```

The records whose evidence quiddity could not prove.

---

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