Custom trace synchronization¶
To integrate a custom trace synchronization, you can implement a Python script that follows the interface defined in the AbstractTraceSynchronization class. This Python script needs to fulfill several requirements to be available as a valid trace synchronization.
The script needs to be located in the
UserPyModulesfolder of the workspace.On the top level of the script, you must specify the variable MODULE_TYPE = ‘TRACE_SYNCHRONIZATION’.
The file needs to contain a class that defines two static class variables:
ID: that uniquely identifies the synchronization. Could be a generated uuid or a simple versioning schema like <class name>_v1
DISPLAY_NAME: that is used to display the synchronization in the user interface.
The class needs to implement the methods GetParameters, GetMasterSignals, GetRecordingSignals and Synchronize.
There must not be two synchronizations with the same ID.
Newly added sychnronizations are available after refreshing the user libraries. You can do this in the menu “Extras”.
AbstractTraceSynchronization¶
- class traceAnalysisAPI.customsynchro.AbstractTraceSynchronization¶
- ID : str¶
unique ID of the synchronization method
- DISPLAY_NAME : str¶
human-readable name of the synchronization method
- classmethod GetParameters() list[ParameterDefinition]¶
Returns a list of parameter definitions required by the custom synchronization.
- classmethod GetMasterSignals() list[SignalDefinition]¶
Returns signal definitions required by the custom synchronization as master signals.
- classmethod GetRecordingSignals() list[SignalDefinition]¶
Returns signal definitions required by the custom synchronization as recording signals.
- abstractmethod Synchronize(masterSignals: dict[str, Signal], recordingSignals: dict[str, Signal], parameters: dict[str, object]) float¶
Returns a calculated time offset in trace time (usually seconds) to synchronize the traces with the master signals.
ParameterDefinition¶
- class traceAnalysisAPI.customsynchro.ParameterDefinition¶
ParameterDefinition(name: ‘str’, description: ‘str’ = ‘’, default: ‘Any’ = None)
- name : str¶
Name of the parameter
-
description : str =
''¶ Description of the parameter
-
default : Any =
None¶ Default value of the parameter
SignalDefinition¶
- class traceAnalysisAPI.customsynchro.SignalDefinition¶
SignalDefinition(name: ‘str’, description: ‘str’ = ‘’, optional: ‘bool’ = False)
- name : str¶
Name of the signal
-
description : str =
''¶ Description of the signal
-
optional : bool =
False¶ Whether the signal is optional
Signal¶
- class traceAnalysisAPI.customsynchro.Signal¶
- GetMappingItemName() str¶
Returns the name of the mapping item this signal relates to.
- Returns:
Name of the mapping item
- GetTimestamps() ndarray¶
Returns a list of timestamps corresponding to the signal values.
- Returns:
List of timestamps
- GetValues() ndarray¶
Returns a list of signal values.
- Returns:
List of tuples (timestamp, value)
Example¶
from __future__ import annotations
from dataclasses import dataclass
MODULE_TYPE = 'TRACE_SYNCHRONIZATION'
@dataclass
class SignalDefinition:
name: str
description: str = ''
optional: bool = False
@dataclass
class ParameterDefinition:
name: str
description: str = ''
default: object = None
class Signal:
def GetMappingItemName(self) -> str:
""""""
def GetTimestamps(self) -> list[float]:
""""""
def GetValues(self) -> list[object | None]:
""""""
class ExpectedValueSync:
DISPLAY_NAME = 'ExpectedValue'
ID = 'ExpectedValueSync_v1'
@classmethod
def GetParameters(cls) -> list[ParameterDefinition]:
return [
ParameterDefinition(
'expectedValue',
description='the description is shown as help text',
default='2.5',
),
]
@classmethod
def GetMasterSignals(cls) -> list[SignalDefinition]:
return [
SignalDefinition(
'SignalA', description='signal that value should match', optional=False
)
]
@classmethod
def GetRecordingSignals(cls) -> list[SignalDefinition]:
return [
SignalDefinition(
'SignalB', description='signal that value should match', optional=False
)
]
def Synchronize(
self,
masterSignals: dict[str, Signal],
recordingSignals: dict[str, Signal],
parameters: dict[str, object],
) -> float:
tsMaster = self._FindValue(
parameters['expectedValue'],
masterSignals['SignalA'],
)
tsRec = self._FindValue(
parameters['expectedValue'],
recordingSignals['SignalB'],
)
if tsMaster is None or tsRec is None:
raise ValueError('Could not find value for one of the signals')
return tsMaster - tsRec
def _FindValue(self, expValue: float, signal: Signal):
for ts, value in zip(signal.GetTimestamps(), signal.GetValues()):
if value == expValue:
return ts
return None