API reference - A121

Contents

API reference - A121#

This page provides an auto-generated summary of Acconeer Exploration Tool’s A121 API.

Configurations#

Session#

class acconeer.exptool.a121.SessionConfig(arg: SensorConfig | dict[int, SensorConfig] | list[dict[int, SensorConfig]] | None = None, *, extended: bool | None = None, update_rate: float | None = None)#

Session configuration

The session configuration defines the highest level of configuration available in Exploration Tool. It mainly consists of one or several sensor configurations (SensorConfig) for the server to run. It also sets the update rate for the server, and the data format (“extended”) returned from the client.

Mapping from sensor ID to sensor config is done here in the session config. For example, if you want to want to use sensor 2, you can do:

SessionConfig({2: SensorConfig(start_point=123)})

The default sensor ID is 1. Going further, you may run multiple sensors at the same time (in parallel) like this:

SessionConfig(
    {
        2: SensorConfig(start_point=123),
        3: SensorConfig(start_point=456),
    }
)

The dictionary shown above forms a group of sensor configs. Further extending upon this, you may specify multiple groups which are run in sequence, like this:

SessionConfig(
    [
        {
            2: SensorConfig(start_point=123),
            3: SensorConfig(start_point=456),
        },
        {
            2: SensorConfig(start_point=789),
        },
    ]
)

You may reuse the same sensor across groups. If a sensor is used multiple times, a reconfiguration will be done prior to each measurement.

A session config with multiple sensor configs (in a single group or multiple) is considered “extended”. This is reflected in the shape of some return types. A SessionConfig with a single SensorConfig is not extended, but the return values can be passed as extended with the keyword argument extended=True, see below:

>>> SessionConfig([{1: SensorConfig()}])
SessionConfig(groups=[{1: ...}], ..., extended=False)
>>> SessionConfig([{1: SensorConfig(), 2: SensorConfig()}])
SessionConfig(groups=[{1: ..., 2: ...}], ..., extended=True)
>>> SessionConfig([{1: SensorConfig()}], extended=True)
SessionConfig(groups=[{1: ...}], ..., extended=True)
Parameters:
  • arg – The sensor configuration(s).

  • extended – Forces whether to use the extended format or not. If not given (= None), the extended format will be used automatically if multiple sensor configs are given.

  • update_rate – The update rate limit on the server. Defaults to None, not limiting the rate.

Raises:

ValueError – If the session config must be extended but extended=False.

property extended: bool#

Whether or not the extended format is used

property groups: list[dict[int, SensorConfig]]#

The sensor config groups of this session

property update_rate: float | None#

The server update rate limit in Hz

Must be > 0 or None, where None means unlimited.

validate() None#

Performs self-validation and validation of its sensor configs

Raises:

ValidationError – If anything is invalid.

property sensor_id: int#

Retrieves the sole sensor ID

Raises:

RuntimeError – If this session config is extended

property sensor_config: SensorConfig#

Retrieves the sole sensor config

Raises:

RuntimeError – If this session config is extended

Sensor#

class acconeer.exptool.a121.SensorConfig(*, subsweeps: list[SubsweepConfig] | None = None, num_subsweeps: int | None = None, sweeps_per_frame: int = 1, sweep_rate: float | None = None, frame_rate: float | None = None, continuous_sweep_mode: bool = False, double_buffering: bool = False, inter_frame_idle_state: IdleState = IdleState.DEEP_SLEEP, inter_sweep_idle_state: IdleState = IdleState.READY, start_point: int | None = None, num_points: int | None = None, step_length: int | None = None, profile: Profile | None = None, hwaas: int | None = None, receiver_gain: int | None = None, enable_tx: bool | None = None, enable_loopback: bool | None = None, phase_enhancement: bool | None = None, prf: PRF | None = None)#

Sensor configuration

The sensor config represents a 1-1 mapping to the RSS service config.

By default, the sensor config holds a single SubsweepConfig. The parameters defined by the subsweep config, like start_point, can be accessed via the sensor config. If multiple subsweeps are used, those parameters must be accessed via their respective subsweep configs.

For example, a sensor config can be created like this:

SensorConfig(sweeps_per_frame=16, start_point=123)

Note that the start_point is implicitly set in the underlying subsweep config. If you want to explicitly set the subsweep config(s), you can do

SensorConfig(
    sweeps_per_frame=16,
    subsweeps=[
        SubsweepConfig(start_point=123),
    ],
)

Parameters can also be accessed via the class attributes:

sensor_config = SensorConfig()
sensor_config.sweeps_per_frame = 16
sensor_config.start_point = 123

If you want to use multiple subsweeps with this style of setting/getting the attributes, you can do like this:

sensor_config = SensorConfig(num_subsweeps=3)
sensor_config.sweeps_per_frame = 16
sensor_config.subsweeps[0].start_point = 123

Note

The sensor config does not control on which sensor it should be run. That is handled by the SessionConfig.

Parameters:
  • subsweeps – The list of subsweeps to initialize with. May not be combined with num_subsweeps.

  • num_subsweeps – Initialize with a given number of subsweeps. May not be combined with subsweeps.

Raises:
  • ValueError – If subsweeps and num_subsweeps are both given.

  • ValueError – If the given list of subsweeps is empty.

  • ValueError – If subsweeps parameters are both given implicitly and via subsweeps.

property hwaas: int#

Hardware accelerated average samples (HWAAS)

Each data point can be sampled several times and the sensor hardware then produces an average value of those samples. The time needed to measure a sweep is roughly proportional to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS could be decreased but this leads to lower SNR.

HWAAS must be between 1 and 511 inclusive.

property start_point: int#

Starting point of the sweep

The starting point of the sweep. The corresponding start in millimeter is approximately start_point * 2.5 mm.

property num_points: int#

Number of data points to measure

The number of data points to measure in a sweep.

property step_length: int#

Step length in a sweep

This sets the number of steps to have between each data point.

The corresponding distance between each data point is step_length * 2.5 mm.

property profile: Profile#

Profile

Each profile consists of a number of settings for the sensor that configures the RX and TX paths. Lower profiles have higher depth resolution while higher profiles have higher radar loop gain.

property receiver_gain: int#

Receiver gain setting

Must be a value between 0 and 23 inclusive where 23 is the highest gain and 0 the lowest.

Lower gain gives higher SNR. However, too low gain may result in quantization, lowering SNR. Too high gain may result in saturation, corrupting the data.

property enable_tx: bool#

Enable or disable the transmitter

If set to True, TX is enabled. This will enable the radio transmitter. By turning the transmitter off the RX noise floor can be measured.

property enable_loopback: bool#

Enable or disable loopback

Enabling loopback will activate an internal route between TX and RX in the sensor. The signal will take this route instead of being transmitted out of the sensor.

Note, loopback can’t be enabled together with profile 2.

property phase_enhancement: bool#

Enable or disable phase enhancement

If enabled, the data phase will be enhanced such that coherent distance filtering can be applied. Given a single reflection from an object, the phase will appear as “flat” around the amplitude peak.

Enabling the phase enhancement increases the processing execution time.

property prf: PRF#

Pulse Repetition Frequency (PRF)

Pulse Repetition Frequency, PRF, is the frequency at which pulses are sent out from the radar system. The measurement time is approximately proportional to the PRF. The higher the PRF, the shorter the measurement time.

This parameter sets the Maximum Measurable Distance, MMD, that can be achieved. MMD is the maximum value for the end point, i.e., the start point + (number of points * step length). For example, an MMD of 7.0 m means that the range cannot be set further out than 7.0 m.

It also sets the Maximum Unambiguous Range, MUR, that can be achieved. MUR is the maximum distance at which an object can be located to guarantee that its reflection corresponds to the most recent transmitted pulse. Objects farther away than the MUR may fold into the measured range. For example, with a MUR of 11.5 m, an object at 13.5 m could become visible at 2 m.

PRF Setting

PRF

MMD

MUR

PRF_19_5_MHZ [*]

19.5 MHz

3.1 m

7.7 m

PRF_15_6_MHZ

15.6 MHz

5.1 m

9.6 m

PRF_13_0_MHZ

13.0 MHz

7.0 m

11.5 m

PRF_8_7_MHZ

8.7 MHz

12.7 m

17.3 m

PRF_6_5_MHZ

6.5 MHz

18.5 m

23.1 m

PRF_5_2_MHZ

5.2 MHz

24.3 m

28.8 m

property subsweep: SubsweepConfig#

Retrieves the sole SubsweepConfig

Raises:

AttributeError – If num_subsweeps > 1

property subsweeps: list[SubsweepConfig]#

The list of subsweep configs

property num_subsweeps: int#

The number of subsweep configs

validate() None#

Performs self-validation and validation of its subsweep configs

Raises:

ValidationError – If anything is invalid.

property sweeps_per_frame: int#

Sweeps per frame (SPF)

The number of sweeps that will be captured in each frame (measurement).

Must be > 0.

property sweep_rate: float | None#

Sweep rate

The sweep rate for sweeps in a frame (measurement).

In Hz. Must be > 0 or None, where None is interpreted as max sweep rate.

property frame_rate: float | None#

Frame rate

Setting the frame rate to unlimited means that the rate is not limited by the sensor but the rate that the host acknowledge and reads out the measurement data.

In Hz. Must be > 0 or None, where None is interpreted as unlimited.

property continuous_sweep_mode: bool#

Continuous sweep mode (CSM)

With CSM, the sensor timing is set up to generate a continuous stream of sweeps, even if more than one sweep per frame is used. The interval between the last sweep in one frame to the first sweep in the next frame becomes equal to the interval between sweeps within a frame (given by the sweep rate).

It ensures that:

‘frame rate’ = ‘sweep rate’ / ‘sweeps per frame’

While the frame rate parameter can be set to approximately satisfy this condition, using CSM is more precise.

If only one sweep per frame is used, CSM has no use since a continuous stream of sweeps is already given (if a fixed frame rate is used).

The main use for CSM is to allow reading out data at a slower rate than the sweep rate, while maintaining that sweep rate continuously.

Note that in most cases, double buffering must be enabled to allow high rates without delays.

Constraints:

property double_buffering: bool#

Double buffering

If enabled, the sensor buffer will be split in two halves reducing the maximum number of samples. A frame can be read while sampling is done into the other buffer.

When using double buffering, measurements coinciding with SPI activity may have distorted phase. To mitigate this issue, applying a median filter is recommended.

property inter_frame_idle_state: IdleState#

Inter frame idle state

The inter frame idle state is the state the sensor idles in between each frame.

Idle state Deep sleep is the deepest state where as much of the sensor hardware as possible is shut down and idle state Ready is the lightest state where most of the sensor hardware is kept on.

Deep sleep is the slowest to transition from while Ready is the fastest.

The inter_frame_idle_state of the frame must be deeper or the same as the inter_sweep_idle_state .

property inter_sweep_idle_state: IdleState#

Inter sweep idle state

The inter sweep idle state is the state the sensor idles in between each sweep in a frame.

Idle state Deep sleep is the deepest state where as much of the sensor hardware as possible is shut down and idle state Ready is the lightest state where most of the sensor hardware is kept on.

Deep sleep is the slowest to transition from while Ready is the fastest.

Subsweep#

class acconeer.exptool.a121.SubsweepConfig(*, start_point: int = 80, num_points: int = 160, step_length: int = 1, profile: Profile = Profile.PROFILE_3, hwaas: int = 8, receiver_gain: int = 16, enable_tx=True, enable_loopback=False, phase_enhancement=False, prf: PRF = PRF.PRF_15_6_MHz)#

Subsweep configuration

The subsweep config represents a 1-1 mapping to the RSS service subsweep config.

Normally used as a part of the SensorConfig. Multiple group configurations are required when certain parameters cannot be configured in subsweep config.

start_point: int#

Starting point of the sweep

The starting point of the sweep. The corresponding start in millimeter is approximately start_point * 2.5 mm.

num_points: int#

Number of data points to measure

The number of data points to measure in a sweep.

step_length: int#

Step length in a sweep

This sets the number of steps to have between each data point.

The corresponding distance between each data point is step_length * 2.5 mm.

profile: Profile#

Profile

Each profile consists of a number of settings for the sensor that configures the RX and TX paths. Lower profiles have higher depth resolution while higher profiles have higher radar loop gain.

hwaas: int#

Hardware accelerated average samples (HWAAS)

Each data point can be sampled several times and the sensor hardware then produces an average value of those samples. The time needed to measure a sweep is roughly proportional to the number of averaged samples. Hence, if there is a need to obtain a higher update rate, HWAAS could be decreased but this leads to lower SNR.

HWAAS must be between 1 and 511 inclusive.

receiver_gain: int#

Receiver gain setting

Must be a value between 0 and 23 inclusive where 23 is the highest gain and 0 the lowest.

Lower gain gives higher SNR. However, too low gain may result in quantization, lowering SNR. Too high gain may result in saturation, corrupting the data.

enable_tx: bool#

Enable or disable the transmitter

If set to True, TX is enabled. This will enable the radio transmitter. By turning the transmitter off the RX noise floor can be measured.

enable_loopback: bool#

Enable or disable loopback

Enabling loopback will activate an internal route between TX and RX in the sensor. The signal will take this route instead of being transmitted out of the sensor.

Note, loopback can’t be enabled together with profile 2.

phase_enhancement: bool#

Enable or disable phase enhancement

If enabled, the data phase will be enhanced such that coherent distance filtering can be applied. Given a single reflection from an object, the phase will appear as “flat” around the amplitude peak.

Enabling the phase enhancement increases the processing execution time.

property prf: PRF#

Pulse Repetition Frequency (PRF)

Pulse Repetition Frequency, PRF, is the frequency at which pulses are sent out from the radar system. The measurement time is approximately proportional to the PRF. The higher the PRF, the shorter the measurement time.

This parameter sets the Maximum Measurable Distance, MMD, that can be achieved. MMD is the maximum value for the end point, i.e., the start point + (number of points * step length). For example, an MMD of 7.0 m means that the range cannot be set further out than 7.0 m.

It also sets the Maximum Unambiguous Range, MUR, that can be achieved. MUR is the maximum distance at which an object can be located to guarantee that its reflection corresponds to the most recent transmitted pulse. Objects farther away than the MUR may fold into the measured range. For example, with a MUR of 11.5 m, an object at 13.5 m could become visible at 2 m.

PRF Setting

PRF

MMD

MUR

PRF_19_5_MHZ []

19.5 MHz

3.1 m

7.7 m

PRF_15_6_MHZ

15.6 MHz

5.1 m

9.6 m

PRF_13_0_MHZ

13.0 MHz

7.0 m

11.5 m

PRF_8_7_MHZ

8.7 MHz

12.7 m

17.3 m

PRF_6_5_MHZ

6.5 MHz

18.5 m

23.1 m

PRF_5_2_MHZ

5.2 MHz

24.3 m

28.8 m

validate() None#

Performs self-validation

Raises:

ValidationError – If anything is invalid.

Parameter enums#

Note

The configuration parameter enum values (e.g. 0, 1, 19500000, …) are not to be used directly. They are subject to change at any time.

class acconeer.exptool.a121.PRF(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#

Pulse Repetition Frequency (PRF)

Pulse Repetition Frequency, PRF, is the frequency at which pulses are sent out from the radar system. The measurement time is approximately proportional to the PRF. The higher the PRF, the shorter the measurement time.

This parameter sets the Maximum Measurable Distance, MMD, that can be achieved. MMD is the maximum value for the end point, i.e., the start point + (number of points * step length). For example, an MMD of 7.0 m means that the range cannot be set further out than 7.0 m.

It also sets the Maximum Unambiguous Range, MUR, that can be achieved. MUR is the maximum distance at which an object can be located to guarantee that its reflection corresponds to the most recent transmitted pulse. Objects farther away than the MUR may fold into the measured range. For example, with a MUR of 11.5 m, an object at 13.5 m could become visible at 2 m.

PRF Setting

PRF

MMD

MUR

PRF_19_5_MHZ []

19.5 MHz

3.1 m

7.7 m

PRF_15_6_MHZ

15.6 MHz

5.1 m

9.6 m

PRF_13_0_MHZ

13.0 MHz

7.0 m

11.5 m

PRF_8_7_MHZ

8.7 MHz

12.7 m

17.3 m

PRF_6_5_MHZ

6.5 MHz

18.5 m

23.1 m

PRF_5_2_MHZ

5.2 MHz

24.3 m

28.8 m

PRF_19_5_MHz = (19500000, 3.1, 7.7)#
PRF_15_6_MHz = (15600000, 5.1, 9.6)#
PRF_13_0_MHz = (13000000, 7.0, 11.5)#
PRF_8_7_MHz = (8700000, 12.7, 17.3)#
PRF_6_5_MHz = (6500000, 18.5, 23.1)#
PRF_5_2_MHz = (5200000, 24.3, 28.8)#
property frequency: int#
property maximum_measurable_distance: float#
property mmd: float#
property maximum_unambiguous_range: float#
property mur: float#
class acconeer.exptool.a121.IdleState(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#

Idle state

DEEP_SLEEP = 0#
SLEEP = 1#
READY = 2#
is_deeper_than(other: IdleState) bool#
class acconeer.exptool.a121.Profile(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#
PROFILE_1 = 1#
PROFILE_2 = 2#
PROFILE_3 = 3#
PROFILE_4 = 4#
PROFILE_5 = 5#

Entities#

RSS representations#

class acconeer.exptool.a121.Result(*, data_saturated, frame_delayed, calibration_needed, temperature, frame: ndarray[Any, dtype[Any]], tick, context: ResultContext)#

Represents the RSS processing_result.

data_saturated: bool#

Indication of sensor data being saturated, can cause data corruption. Lower the receiver gain if this indication is set.

frame_delayed: bool#

Indication of a delayed frame. The frame rate might need to be lowered if this indication is set.

calibration_needed: bool#

Indication of calibration needed. The sensor calibration needs to be redone if this indication is set.

temperature: int#

Temperature in sensor during measurement (in degree Celsius). Notice that this has poor absolute accuracy.

tick: int#

Server tick when the server got the interrupt from the sensor

property frame: ndarray[Any, dtype[complex128]]#

Frame data in a complex float data format

2-D with dimensions (sweep, distance).

property subframes: list[ndarray[Any, dtype[complex128]]]#

Frame split up into subframes, one for every subsweep config used

property tick_time: float#

Tick converted to a time in seconds

class acconeer.exptool.a121.Metadata(*, frame_data_length: int, sweep_data_length: int, subsweep_data_offset: ndarray[Any, dtype[int64]], subsweep_data_length: ndarray[Any, dtype[int64]], calibration_temperature: int, tick_period: int, base_step_length_m: float, max_sweep_rate: float, high_speed_mode: bool | None = None)#

Represents a super set of the RSS processing_metadata.

property frame_data_length: int#

Number of elements in the frame

property sweep_data_length: int#

Number of elements in the sweep

property subsweep_data_offset: ndarray[Any, dtype[int64]]#

Offset to the subsweeps data

property subsweep_data_length: ndarray[Any, dtype[int64]]#

Number of elements in the subsweeps

property calibration_temperature: int#

Temperature during calibration

property tick_period: int#

Target tick period if update rate is set, otherwise 0

property base_step_length_m: float#

Base step length in meter

property max_sweep_rate: float#

Maximum sweep rate that the sensor can provide for the given configuration

property high_speed_mode: bool | None#

Flag indicating if high speed mode is used. If true, it means that the sensor has been configured in a way where it can optimize its measurements and obtain a high max sweep rate.

Configuration limitations to enable high speed mode: - Continuous sweep mode: off - Inter sweep idle state: Ready - Subsweeps: 1 - Profile 3-5

Note: Available in RSS version > 0.8.0

property frame_shape: Tuple[int, int]#

The frame shape this Metadata defines

to_dict() dict[str, Any]#
classmethod from_dict(d: dict[str, Any]) Metadata#
to_json() str#
classmethod from_json(json_str: str) Metadata#
class acconeer.exptool.a121.SensorCalibration(*, temperature: int, data: str)#

Represents the RSS cal_result and cal_info.

temperature: int#

The calibration temperature

data: str#

The calibration data

to_dict() dict[str, Any]#
classmethod from_dict(d: dict[str, Any]) SensorCalibration#
to_json() str#
classmethod from_json(json_str: str) SensorCalibration#
to_h5(group: Group) None#
classmethod from_h5(group: Group) SensorCalibration#

System info#

class acconeer.exptool.a121.ClientInfo(*, socket: SocketInfo | None = None, serial: SerialInfo | None = None, usb: USBInfo | None = None, mock: MockInfo | None = None)#
socket: SocketInfo | None#
serial: SerialInfo | None#
usb: USBInfo | None#
mock: MockInfo | None#
to_dict() dict[str, Any]#
classmethod from_dict(d: dict[str, Any]) ClientInfo#
to_json() str#
classmethod from_json(json_str: str) ClientInfo#
class acconeer.exptool.a121.ServerInfo(*, rss_version: str, sensor_count: int, ticks_per_second: int, sensor_infos: dict[int, SensorInfo], hardware_name: str | None = None, max_baudrate: int | None = None)#
rss_version: str#
sensor_count: int#
ticks_per_second: int#
sensor_infos: dict[int, SensorInfo]#
hardware_name: str | None#
max_baudrate: int | None#
property parsed_rss_version: Version#
property connected_sensors: list[int]#
to_dict() dict[str, Any]#
classmethod from_dict(d: dict[str, Any]) ServerInfo#
to_json() str#
classmethod from_json(json_str: str) ServerInfo#
class acconeer.exptool.a121.SensorInfo(*, connected: bool, serial: str | None = None)#

Holds information about a single sensor slot on a host.

connected: bool#
serial: str | None#
to_dict() dict[str, Any]#
classmethod from_dict(d: dict[str, Any]) SensorInfo#
to_json() str#
classmethod from_json(json_str: str) SensorInfo#

Client#

class acconeer.exptool.a121.Client(*args: Any, **kwargs: Any)#
abstract close() None#

Closes the connection to the host

abstract get_next() Result | list[dict[int, Result]]#

Gets results from the server.

Returns:

A Result if the setup SessionConfig.extended is False, list[dict[int, Result]] otherwise.

Raises:

ClientError if Client’s session is not started.

classmethod open(ip_address: str | None = None, tcp_port: int | None = None, serial_port: str | None = None, usb_device: str | bool | None = None, mock: bool | None = None, override_baudrate: int | None = None, flow_control: bool = True, generation: str | None = 'a121') Self#

Open a new client

abstract setup_session(config: SensorConfig | SessionConfig, calibrations: dict[int, SensorCalibration] | None = None) Metadata | list[dict[int, Metadata]]#

Sets up the session specified by config.

Parameters:
  • config – The session to set up.

  • calibrations – An optional dict with SensorCalibration for the session.

Raises:

ValueError if the config is invalid.

Returns:

Metadata if config.extended is False, list[dict[int, Metadata]] otherwise.

abstract start_session() None#

Starts the already set up session.

After this call, the server starts streaming data to the client.

Raises:

ClientError if Client’s session is not set up.

abstract stop_session() None#

Stops an on-going session

Raises:

ClientError if Client’s session is not started.

property calibrations: dict[int, SensorCalibration]#

Returns a dict with a SensorCalibration per used sensor for the current session:

For example, if session_setup was called with

client.setup_session(
    SessionConfig({1: SensorConfig(), 3: SensorConfig()}),
)

this attribute will return {1: SensorCalibration(…), 3: SensorCalibration(…)}

property calibrations_provided: dict[int, bool]#

Returns whether a calibration was provided for each sensor in setup_session. For example, if setup_session was called with

client.setup_session(
    SessionConfig({1: SensorConfig(), 2: SensorConfig()}),
    calibrations={2: SensorCalibration(...)},
)

this attribute will return {1: False, 2: True}

property client_info: ClientInfo#

The ClientInfo.

abstract property connected: bool#

Whether this Client is connected.

property extended_metadata: list[dict[int, Metadata]]#

The extended Metadata for the current session

abstract property server_info: _ServerInfoT#

The ServerInfo.

property session_config: SessionConfig#

The SessionConfig for the current session

property session_is_setup: bool#

Whether this Client has a session set up.

property session_is_started: bool#

Whether this Client’s session is started.

Recording#

Recorders#

class acconeer.exptool.a121.H5Recorder(path_or_file: PathOrH5File, attachable: t.Optional[RecorderAttachable[Recorder[SessionConfig, t.List[t.Dict[int, Metadata]], t.List[t.Dict[int, Result]], ServerInfo]]] = None, mode: str = 'x', *, _chunk_size: t.Optional[int] = None, _lib_version: t.Optional[str] = None, _timestamp: t.Optional[str] = None, _uuid: t.Optional[str] = None)#

Recorder writing directly to an HDF5 file

Parameters:
  • path_or_file

    If a path-like object, by default (depending on mode below) an HDF5 file is created at that path. When stopping, the file is closed.

    If an h5py.File, that file is used as-is. In this case, the file is not closed when stopping.

  • attachable – A Client that the recorder will be attached to. When a recorder is attached to a Client, all metadata and data frames will be recorded.

  • mode – The file mode to use if a path-like object was given for path_or_file. Default value is ‘x’, meaning that we open for exclusive creation, failing if the file already exists.

  • _chunk_size

    If given, data will be written to file every _chunk_size samples.

    If not given, data will be written at least every 512:th sample, or at least once per second, whichever comes first.

    Setting a small chunk size (e.g. 1) may degrade performance for high sample rates.

    Internal parameter, subject to change.

Records#

class acconeer.exptool.a121.Record#

Record representing all data needed to recreate multiple sessions

A Record also is a SessionRecord, but its session-related accessors (like results, session_config) will raise an error if this Record contains multiple sessions/SessionRecords.

abstract property client_info: ClientInfo#

Client info

abstract property lib_version: str#

The version of the acconeer.exptool library which created the record

abstract property server_info: ServerInfo#

Server info

abstract property timestamp: str#

Creation timestamp

abstract property uuid: str#

UUID

abstract session(session_index: int) SessionRecord#

Gets the session at session_index

abstract property num_sessions: int#

The number of sessions in this record

property extended_metadata: list[dict[int, Metadata]]#

The extended metadata of the sole session in this Record

Raises:

ValueError if this record contains multiple sessions

property extended_results: Iterator[list[dict[int, Result]]]#

The extended results of the sole session in this Record

Raises:

ValueError if this record contains multiple sessions

property extended_stacked_results: list[dict[int, StackedResults]]#

The extended stacked results of the sole session in this Record

Raises:

ValueError if this record contains multiple sessions

property num_frames: int#

The number of frames of the sole session in this Record

Raises:

ValueError if this record contains multiple sessions

property session_config: SessionConfig#

The session config of the sole session in this Record

Raises:

ValueError if this record contains multiple sessions

property sensor_id: int#

The sole session id of the sole session in this Record

Raises:

ValueError if this record contains multiple sessions

property calibrations: dict[int, SensorCalibration]#

The calibrations of the sole session in this Record

Raises:

ValueError if this record contains multiple sessions

property calibrations_provided: dict[int, bool]#

A mapping of reused (provided) calibrations of the sole session in this Record

Raises:

ValueError if this record contains multiple sessions

class acconeer.exptool.a121.PersistentRecord#

Record that wraps a file on disk

Data is lazily loaded from the underlying file on demand.

abstract close() None#

Close the underlying file

class acconeer.exptool.a121.StackedResults(*, data_saturated: ndarray[Any, dtype[bool]], frame_delayed: ndarray[Any, dtype[bool]], calibration_needed: ndarray[Any, dtype[bool]], temperature: ndarray[Any, dtype[bool]], frame: ndarray[Any, dtype[Any]], tick: ndarray[Any, dtype[int64]], context: ResultContext)#

Stacked results

For loading/processing data.

Representation of multiple Result stacked together. Scalar values, like Result.data_saturated, become 1-D arrays of the same type. The Result.frame, which is originally a 2-D array, becomes a 3-D array where the frames are stacked in the first dimension.

See Result for details on the attributes/properties.

data_saturated: ndarray[Any, dtype[bool]]#
frame_delayed: ndarray[Any, dtype[bool]]#
calibration_needed: ndarray[Any, dtype[bool]]#
temperature: ndarray[Any, dtype[bool]]#
tick: ndarray[Any, dtype[int64]]#
property frame: ndarray[Any, dtype[complex128]]#
property subframes: list[ndarray[Any, dtype[complex128]]]#
property tick_time: ndarray[Any, dtype[float64]]#

Open/load/save functions#

acconeer.exptool.a121.load_record(path_or_file: PathOrH5File) Record#

Load a record from file

Unlike open_record(), this functions loads the data into memory immediately. The file handle is not kept open.

Returns:

A Record with the content of the given file

acconeer.exptool.a121.open_record(path_or_file: PathOrH5File) PersistentRecord#

Open a record from file

Since this function returns a PersistentRecord, data is not immediately loaded into memory. Rather, data is lazily loaded from the underlying file on demand.

Either a path or an opened file (h5py.File) may be given. If a path is given, the file will be opened by this function, and must be closed again by the user. The recommended way to do this is by using the context manager of the returned persistent record, like:

with a121.open_record("path/to/my/file.h5") as record:
    record.timestamp

Tip

Unless you’re dealing with very large files, use load_record() instead.

Returns:

A PersistentRecord wrapping the given file

acconeer.exptool.a121.save_record(path_or_file: PathOrH5File, record: Record) None#

Alias for save_record_to_h5()

acconeer.exptool.a121.save_record_to_h5(path_or_file: PathOrH5File, record: Record) None#

Save a record to a HDF5 file

Utility functions#

acconeer.exptool.a121.complex_array_to_int16_complex(array: ndarray[Any, dtype[complex128]]) ndarray[Any, dtype[Any]]#

Converts an array with plain complex dtype (non-structured) into an array with dtype = INT_16_COMPLEX (structured with parts “real” and “imag”) using numpy.round.

acconeer.exptool.a121.iterate_extended_structure(structure: Sequence[Mapping[int, ValueT]]) Iterator[Tuple[int, int, ValueT]]#

Iterates over the elements of the extended structure.

Returns:

Iterator of (<group id>, <sensor id>, <element>)

acconeer.exptool.a121.iterate_extended_structure_values(structure: Sequence[Mapping[int, ValueT]]) Iterator[ValueT]#

Iterates like iterate_extended_structure but throws away group id and sensor id.

acconeer.exptool.a121.zip_extended_structures(structure_a: list[dict[int, S]], structure_b: list[dict[int, T]]) list[dict[int, Tuple[S, T]]]#

Zip structures according to group id and sensor id.

Typical use case is reordering extended structures before iterating.

Example:

>>> a = [{1: "a_1", 2: "a_2"}, {1: "a_3"}]
>>> b = [{1: "b_1", 2: "b_2"}, {1: "b_3"}]
>>> zip_extended_structures(a, b)
[{1: ('a_1', 'b_1'), 2: ('a_2', 'b_2')}, {1: ('a_3', 'b_3')}]
acconeer.exptool.a121.zip3_extended_structures(structure_a: list[dict[int, S]], structure_b: list[dict[int, T]], structure_c: list[dict[int, U]]) list[dict[int, Tuple[S, T, U]]]#

Zip structures according to group id and sensor id.

Typical use case is reordering extended structures before iterating.

Example:

>>> a = [{1: "a_1", 2: "a_2"}, {1: "a_3"}]
>>> b = [{1: "b_1", 2: "b_2"}, {1: "b_3"}]
>>> c = [{1: "c_1", 2: "c_2"}, {1: "c_3"}]
>>> zip3_extended_structures(a, b, c)
[{1: ('a_1', 'b_1', 'c_1'), 2: ('a_2', 'b_2', 'c_2')}, {1: ('a_3', 'b_3', 'c_3')}]

Algo#

Warning

The acconeer.exptool.a121.algo package is currently an unstable API and may change at any time.

Utility functions#

acconeer.exptool.a121.algo.find_peaks(abs_sweep: ndarray[Any, dtype[float64]], threshold: ndarray[Any, dtype[float64]]) list[int]#

Identifies peaks above threshold.

A peak is defined as a point with greater value than its two neighboring points and all three points are above the threshold.

Parameters:
  • abs_sweep – Absolute value of mean sweep.

  • threshold – Array of values, defining the threshold throughout the sweep.

acconeer.exptool.a121.algo.get_distance_filter_coeffs(profile: Profile, step_length: int, narrow_filter: bool = False) Any#

Calculates the IIR coefficients corresponding to a matched filter, based on the profile and the step length.

Narrow filter increase the bandwidth of the filter, yielding a less smeared envelope after filtering.

acconeer.exptool.a121.algo.get_distance_filter_edge_margin(profile: Profile, step_length: int) int#

Calculates the number of points required for filter initialization when performing distance filtering, using the filter coefficients supplied by the function get_distance_filter_coeffs.

acconeer.exptool.a121.algo.get_distances_m(config: SensorConfig | SubsweepConfig, metadata: Metadata) ndarray[Any, dtype[float64]]#

Returns an array of all distances measured by the config. The distances are returned in the same order as found in the result frame (acconeer.exptool.a121.Result.frame())

acconeer.exptool.a121.algo.get_temperature_adjustment_factors(reference_temperature: float, current_temperature: float, profile: Profile) Tuple[float, float]#

Calculate temperature compensation for mean sweep and background noise(tx off) standard deviation.

The signal adjustment models how the amplitude level fluctuates with temperature. If the same object is measured against while the temperature changes, the amplitude level should be multiplied with this factor. The temperature difference should be calculated by subtracting the (calibration) recorded temperature from the measured.

Example of usage: reference_temperature (recorded temperature during calibration) reference_amplitude (recorded amplitude during calibration)

measurement_temperature (temperature at measurement time)

signal_adjustment_factor, deviation_adjustment_factor = get_temperature_adjustment_factors(reference_temperature, measurement_temperature, profile)

reference_amplitude_new = reference_amplitude * signal_adjustment_factor

The reference_amplitude_new is an approximation of what the calibrated amplitude would be at the new temperature.

E.g. When the temperature falls 60 degrees, the amplitude (roughly) doubles. This yields a signal_adjustment_factor of (about) 2.

The signal adjustment model is follows 2 ** (temperature_diff / model_parameter), where model_parameter reflects the temperature difference relative the reference temperature, required for the amplitude to double/halve.

The deviation_adjustment_factor works the same way, but is applied to a measurement taken with the Tx off. So if instead of measurement_amplitude, we have a measurement of tx_off. The procedure for calculating this is to take the same configuration as the application will use, but turning off the Tx. This calibration value is multiplied with the deviation_adjustment_factor.

acconeer.exptool.a121.algo.interpolate_peaks(abs_sweep: ndarray[Any, dtype[float64]], peak_idxs: list[int], start_point: int, step_length: int, step_length_m: float) Tuple[list[float], list[float]]#

Quadratic interpolation around a peak using the amplitudes of the peak and its two neighboring points.

Derivation: https://math.stackexchange.com/questions/680646/get-polynomial-function-from-3-points

Parameters:
  • abs_sweep – Absolute value of mean sweep.

  • peak_idxs – List containing indexes of identified peaks.

  • start_point – Start point.

  • step_length – Step length in points.

  • step_length_m – Step length in meters.

acconeer.exptool.a121.algo.select_prf(breakpoint: int, profile: Profile) PRF#

Calculates the highest possible PRF for the given breakpoint.

Parameters:
  • breakpoint – Distance in the unit of points.

  • profile – Profile.