# ChannelMap

## class ChannelMap( channels: dict[str, str | None]=<factory>, include_unmapped: bool = False, instrument: str | None = None, )[source]

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object "(in Python v3.15)")

Which pymeasure properties publish, and under which channel names.

Generate one from an instrument, save it, edit the `channel` of each entry (or set it to
`null` to stop publishing that property), and pass the file or object to
[`PymeasureInstrument`](https://dev.nominal.io/instro/ref/library/instro.pymeasure.PymeasureInstrument.md#instro.pymeasure.PymeasureInstrument "instro.pymeasure.PymeasureInstrument") or [`attach`](https://dev.nominal.io/instro/ref/library/instro.pymeasure.attach.md#instro.pymeasure.attach "instro.pymeasure.attach").

A command channel is the mapped name plus `.cmd`; a measurement channel is the mapped name.
Both sit under the instrument name: `<instrument name>.<mapped name>[.cmd]`.

Variables:
:   - **channels** ([*dict*](https://docs.python.org/3/builtins/stdtypes.html#dict "(in Python v3.15)")*[*[*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)")*,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)") *|* *None**]*) – Attribute path (`"ch_1.voltage_setpoint"`) to channel name (`"ch1.vset"`), or
      `None` to leave that property unpublished.
    - **include_unmapped** ([*bool*](https://docs.python.org/3/builtins/functions.html#bool "(in Python v3.15)")) – Publish properties missing from `channels` under their default names.
    - **instrument** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str "(in Python v3.15)") *|* *None*) – `module.Class` of the instrument the map was generated from; informational.

### channels: dict[str, str | None]

### include_unmapped: bool = False

### instrument: str | None = None

### classmethod defaults() → ChannelMap[source]

Return the map used when none is given: every property under its default name.

### classmethod generate( target: CommonBase | type[CommonBase], ) → ChannelMap[source]

Build a map listing every publishable property of `target` under its default name.

Parameters:
:   **target**

    A pymeasure instrument instance (preferred: it sees channels added in
    `__init__`) or class.

Returns:
:   A [`ChannelMap`](https://dev.nominal.io/instro/ref/library/instro.pymeasure.ChannelMap.md#instro.pymeasure.ChannelMap "instro.pymeasure.ChannelMap") with one entry per property and `include_unmapped=False`.

### classmethod from_dict( data: dict[str, Any], ) → ChannelMap[source]

Parse the JSON-compatible form written by [`to_dict`](https://dev.nominal.io/instro/ref/library/instro.pymeasure.ChannelMap.md#instro.pymeasure.ChannelMap.to_dict "instro.pymeasure.ChannelMap.to_dict").

Each `channels` value may be a channel-name string, `null`, or an object whose
`channel` key holds either; its `kind`/`get`/`set`/`doc` keys are informational.

Raises:
:   [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – The format tag is unknown or an entry is malformed.

### classmethod load( path: str | Path, ) → ChannelMap[source]

Read a map from a JSON file written by [`save`](https://dev.nominal.io/instro/ref/library/instro.pymeasure.ChannelMap.md#instro.pymeasure.ChannelMap.save "instro.pymeasure.ChannelMap.save") (or the `instro pymeasure map` command).

### to_dict( specs: list[ChannelSpec] | None = None, ) → dict[str, Any][source]

Return the JSON-compatible form.

Parameters:
:   **specs**

    Inspection results for the instrument. When given, each entry also records the
    property’s kind, SCPI commands, and docstring to make the file easier to edit.

### save( path: str | Path, target: CommonBase | type[CommonBase] | None = None, ) → None[source]

Write the map as JSON.

Parameters:
:   - **path**

      Destination file.
    - **target**

      Instrument the map belongs to; when given, entries carry each property’s kind,
      SCPI commands, and docstring.

### rename( names: dict[str, str | None], ) → ChannelMap[source]

Set the channel name of each attribute path in `names` (`None` stops publishing it).

Example:

```
channel_map.rename({"ch_1.voltage_setpoint": "out1.v_set", "ch_1.current": "out1.i"})
```

Returns:
:   This map, so calls can be chained.

Raises:
:   [**KeyError**](https://docs.python.org/3/builtins/exceptions.html#KeyError "(in Python v3.15)") – A path is not in the map.

### exclude( *patterns: str, ) → ChannelMap[source]

Stop publishing every attribute path that matches one of the glob `patterns`.

Example:

```
channel_map.exclude("ch_2.*", "ch_3.*")
```

Returns:
:   This map, so calls can be chained.

Raises:
:   [**KeyError**](https://docs.python.org/3/builtins/exceptions.html#KeyError "(in Python v3.15)") – A pattern matches no path, which is usually a typo.

### select( *patterns: str, ) → ChannelMap[source]

Stop publishing every attribute path that matches none of the glob `patterns`.

Example:

```
channel_map.select("ch_1.*")  # publish output 1 only
```

Returns:
:   This map, so calls can be chained.

Raises:
:   [**KeyError**](https://docs.python.org/3/builtins/exceptions.html#KeyError "(in Python v3.15)") – A pattern matches no path, which is usually a typo.

### preview( target: CommonBase | type[CommonBase], name: str | None = None, ) → list[dict[str, str | None]][source]

Show exactly which channels each property publishes, separately for commands and measurements.

Writing a property publishes a [`Command`](https://dev.nominal.io/instro/ref/library/instro.lib.types.Command.md#instro.lib.types.Command "instro.lib.types.Command") on the `command` channel; reading it
publishes a [`Measurement`](https://dev.nominal.io/instro/ref/library/instro.lib.types.Measurement.md#instro.lib.types.Measurement "instro.lib.types.Measurement") on the `measurement` channel. A control has both,
a measurement only the second, a setting only the first.

Example:

```
import pandas as pd
pd.DataFrame(channel_map.preview(supply, "psu"))
```

Parameters:
:   - **target**

      The instrument (instance or class) the map is for.
    - **name**

      Instrument name to prefix, as passed to [`attach`](https://dev.nominal.io/instro/ref/library/instro.pymeasure.attach.md#instro.pymeasure.attach "instro.pymeasure.attach") or [`PymeasureInstrument`](https://dev.nominal.io/instro/ref/library/instro.pymeasure.PymeasureInstrument.md#instro.pymeasure.PymeasureInstrument "instro.pymeasure.PymeasureInstrument").

Returns:
:   One row per property with keys `property`, `kind`, `command`, and `measurement`;
    a channel is `None` when the property doesn’t publish in that direction.

Raises:
:   [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – The map does not fit `target` (see [`resolve`](https://dev.nominal.io/instro/ref/library/instro.pymeasure.ChannelMap.md#instro.pymeasure.ChannelMap.resolve "instro.pymeasure.ChannelMap.resolve")).

### resolve( specs: list[ChannelSpec], ) → dict[str, str][source]

Return attribute path to channel name for every property that publishes.

Parameters:
:   **specs**

    Inspection results for the instrument the map is applied to.

Raises:
:   [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError "(in Python v3.15)") – The map names a path the instrument does not have (a typo, or a pymeasure
    upgrade renamed it), a channel name is invalid or ends in `.cmd`, or two
    properties map to the same channel name.
