# `Monty.SensorModules.SensorModule.Transform`
[🔗](https://github.com/d-led/ex.tbp.monty/blob/v0.1.0/packages/ex_tbp_monty_core/lib/monty/sensor_modules/sensor_module/transform.ex#L1)

One stage of a sensor module's pipeline.

Mirrors `tbp/monty/sensor_modules/sensor_module.py::Transform`, which Monty
declares as a `Protocol` so a config can name any callable. Here it is a
behaviour, and the sensor module stores each transform as `{module, transform}`
— the module that knows how to call it, and the config that says how.

A transform answers the payload it was given, changed. It may make a percept
from the observation, add goals, claim a region, or write telemetry; it may
also pass the payload through untouched, which is what a stage for a feature
this run does not use does.

## Why it also answers itself

Monty's transforms are objects that keep state: a smoothing filter remembers
the frames it has seen, a background model remembers the background. In Elixir
a struct cannot be mutated, so a transform answers the transform it leaves
behind — `{payload, transform}` — and the sensor module keeps that one for the
next step. Same reason samplers answer their stream (`docs/monty-differences.md`
§2.5), and the reason a reset has something to reset (§2.13).

# `t`

```elixir
@type t() :: struct()
```

# `call`

```elixir
@callback call(
  t(),
  Monty.SensorModules.SensorModule.TransformContext.t(),
  Monty.SensorModules.SensorModule.Payload.t()
) :: {Monty.SensorModules.SensorModule.Payload.t(), t()}
```

The payload transformed, and the transform that transformed it.

---

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