Telemetry Recorder

Overview

The Telemetry Recorder is a reusable component that needs to be customised both at compile-time and run-time. A tutorial on how to implement a specific recorder is provided in the Telemetry Recorder Tutorial.

Basic Operation

Usually, a new recording session is started with command Run and stopped with command Idle.

Once a recording session is started and the component is in state On:Operational:Running it will ingest data from various sources and write them to a set of output files located in folder $DATAROOT/component_id/session_id/.

In case the recorder is configured to stop recording on its own it will automatically transition to state On:Operational:Idle once a configurable stop-condition is met. In this case it is not necessary to send the Idle command.

In case a recording session fails the component will transition to state On:Operational:Error which can be left using command Recover.

Common Recording Infrastructure

The Telemetry Recorder and also the Metadata Collector make use of the same common recording infrastructure.

Recording Units

Telemetry Recorder and Metadata Collector components hosts one or more Recording Units, where each unit ingests data from a specific source and writes them into a corresponding FITS file. Note that the output file name corresponds to the unique identifier of the recording unit.

All recording units extend the base class RecordingUnit that defines a common interface and provides basic functionality for all recording unit types.

Common functionality implemented in the base class includes publishing the recording unit state to OLDB and implementing leader follower functionality that enables follower recording units to react to state changes of leader recording units.

To customise a recorder, recording units of different types are constructed and passed to the component via dependency injection. Recording unit configuration happens both at compile-time and at run-time.

The following compile-time configuration options are required by all units:

Parameter

Type

Description

component_id

string

name of the component the unit belongs to

unit_id

string

unique identifier of the recording unit

services

object handle

access to various services

The run-time configuration for these recording units can be found under “/component_name/unit_name” in the Runtime Configuration Repository. Depending on its type, each RecordingUnit can have different settings in this location. All RecordingUnits support the following settings:

Parameter

Type

Description

leader_list

static

list of other recording units that can trigger and stop the recording of this unit

Currently the RTC Toolkit supports the following Recording Units:

  • IpcqRecordingUnit for recording IPCQ shared memory topics into FITS binary tables

  • DataPointRecordingUnit for recording datapoints from the runtime repository into FITS binary tables

  • JsonEventRecordingUnit and TypedEventRecordingUnit for recording events

Note that instrument RTC developers may also implement custom recording units if necessary.

IpcqRecordingUnit

This type of recording unit listens to an IPCQ shared memory topic and writes data sample to its backend.

At compile-time the unit needs to be parametrised with the Shared Memory Topic Type.

At run-time the unit supports the following configuration options:

Parameter

Type

Description

shm_queue_name

static

name of the ipcq

cpu_affinity

static

(optional) CPU affinity setting for the thread that reads from the IPCQ and writes to disk.

telemetry_subset

static

(optional) Only record the given parts of the topic.

subsample_factor

dynamic

Defines how many samples shall be skipped for each read sample.

start_at_sample_id

dynamic

This lets the recording unit wait for a minimum sample_id, before starting the recording and triggering its followers.

stop_after_num_samples

dynamic

This lets the recording unit stop automatically after having recorded the given amount of samples.

The following is an example of an IpcqRecordingUnit configuration in YAML format:

static:
  rec_units:
    ipcq_unit_1:
      shm_queue_name:
        type: RtcString
        value: exampleTelRecQueue
      cpu_affinity:
        type: RtcInt32
        value: 0
      telemetry_subset:
        type: RtcVectorString
        value:
            - intensities
            - slopes
dynamic:
  rec_units:
    ipcq_unit_1:
      subsample_factor:
        type: RtcInt64
        value: 10
      start_at_sample_id:
        type: RtcInt64
        value: 0
      stop_after_num_samples:
        type: RtcInt64
        value: 10

DataPointRecordingUnit

This kind of recording unit is used to record datapoints from the runtime repository.

At compile-time the unit needs to be parametrised with the Datapoint Type and the Datapoint Path (location of the datapoint in the repository).

At run-time the unit supports the following configuration options:

Parameter

Type

Description

capture_mask

static

bit mask to configure wheter data should be captured on_start, on_stop or on_change

The following is an example of a DataPointRecordingUnit configuration in YAML format:

static:
  rec_units:
    dp_unit_2:
      leader_list:
        type: RtcVectorString
        value:
            - ipcq_unit_1
      capture_mask:
        type: RtcInt32
        value: 3

The datapoint recording unit is configured to follow ipcq_unit_1 and to capture the datapoint value on_start (Bit 1) and on on_stop (Bit 2). To also capture data on_change Bit 3 would also need to be set, this would lead to configuration value 7.

JsonEventRecordingUnit and TypedEventRecordingUnit

These recording unit types are used to record events that are emitted by various components.

While the more low-level JsonEventRecordingUnit can record arbitrary JSON events, the more high-level Typed Event Recording Unit can record specific event types.

At compile-time the JsonEventRecordingUnit needs to be parametrised with a fixed TopicName, the TypedEventRecordingUnit needs to be parametrised with a specific EventType. In addition, both units allow the provision of a filter function that can be used to filter out unwanted samples.

Currently these units do not have any run-time configuration options.

Data Recorder

This class is an abstract class that can be used to implement an OutputStage for a Recording Unit. It provides an interface to open and close files, write a tuple and allows removing parts of the tuple from the output. This is used when only a subset of the data should be written. Currently, the only derived class is the FitsRecorder class, that implements this interface to write to a FITS binary table.

FitsRecorder

The FitsRecorder class creates a FITS file containing a single binary table. It is a templated class where the template arguments correspond to the data types to be stored in the binary table. The supported types are:

  • std::string

  • bool

  • uint8_t

  • int8_t

  • int16_t

  • uint16_t

  • int32_t

  • uint32_t

  • int64_t

  • float

  • double

And using the above types in any of these containers:

  • std::vector

  • std::array

  • gsl::span

  • MatrixBuffer

The constructor takes 3 arguments, a discription of the columns (column name and the unit), a list of disabled outputs (can be used to disable output of some columns at runtime), and the name of the FITS binary table extension

Limitations and Known Issues

At this point, the recording infrastructure is not optimised for high performance, there is still room for optimisation to make recording viable at fast loop rates.

Currently, the only output format are FITS binary tables. Additional recording unit types that can record FITS keywords will be added in a sub-sequent release.

Not all event types are supported at the moment e.g. support for certain configuration and coordination event types is still missing. Please use the generic JsonEventRecordingUnit to record such events until the missing parts are implemented in a sub-sequent version.