### Install asammdf Source: https://github.com/danielhrisca/asammdf/blob/master/doc/intro.md Install the asammdf library using pip. For the GUI, install with the 'gui' extra. ```python pip install asammdf # for the GUI pip install asammdf[gui] ``` -------------------------------- ### MDF File Creation and Extension Examples Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Examples demonstrating how to create a new MDF file, append signals, and extend existing data with or without invalidation bits. ```APIDOC ## MDF File Creation and Extension Examples ### Description Examples demonstrating how to create a new MDF file, append signals, and extend existing data with or without invalidation bits. ### Code Examples **Creating and Appending Signals:** ```python from asammdf import MDF, Signal import numpy as np s1 = np.array([1, 2, 3, 4, 5]) s2 = np.array([-1, -2, -3, -4, -5]) s3 = np.array([0.1, 0.04, 0.09, 0.16, 0.25]) t = np.array([0.001, 0.002, 0.003, 0.004, 0.005]) s1 = Signal(samples=s1, timestamps=t, unit='+', name='Positive') s2 = Signal(samples=s2, timestamps=t, unit='-', name='Negative') s3 = Signal(samples=s3, timestamps=t, unit='flts', name='Floats') mdf = MDF(version='4.10') mdf.append([s1, s2, s3], comment='created by asammdf') t = np.array([0.006, 0.007, 0.008, 0.009, 0.010]) ``` **Extending without invalidation bits:** ```python mdf.extend(0, [(t, None), (s1.samples, None), (s2.samples, None), (s3.samples, None)]) ``` **Extending with some invalidation bits:** ```python s1_inv = np.array([0, 0, 0, 1, 1], dtype=bool) mdf.extend(0, [(t, None), (s1.samples, s1_inv), (s2.samples, None), (s3.samples, None)]) ``` ``` -------------------------------- ### Install C-extension Module Source: https://github.com/danielhrisca/asammdf/blob/master/CMakeLists.txt Installs the compiled 'cutils' target to the 'asammdf/blocks' directory within the installation prefix. ```cmake install(TARGETS cutils DESTINATION "asammdf/blocks") ``` -------------------------------- ### Install asammdf using pip Source: https://github.com/danielhrisca/asammdf/blob/master/README.md Use this command to install the asammdf library. For GUI support, install with the 'gui' extra. ```shell pip install asammdf # for the GUI pip install asammdf[gui] ``` ```shell # or for anaconda conda install -c conda-forge asammdf ``` -------------------------------- ### Install Development Dependencies Source: https://github.com/danielhrisca/asammdf/blob/master/CONTRIBUTING.md Install the necessary development dependencies, including asammdf in editable mode, using the provided requirements file. ```bash pip install --requirement requirements.txt ``` -------------------------------- ### Start Time Property Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Accesses the measurement start timestamp of an MDF file. ```APIDOC ## *property* start_time ### Description Gets or sets the measurement start timestamp for the MDF file. ### Returns - **timestamp** (datetime) - The start timestamp of the measurement. ``` -------------------------------- ### MDF Start Time Property Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Provides access to the measurement start timestamp of the MDF file. ```APIDOC ## GET /api/start_time ### Description Getter and setter of the measurement start timestamp. ### Returns #### Success Response (200) - **timestamp** (datetime) - Start timestamp. #### Response Example ```json { "timestamp": "2023-10-27T10:00:00" } ``` ``` -------------------------------- ### CMake Project Setup Source: https://github.com/danielhrisca/asammdf/blob/master/CMakeLists.txt Initializes the CMake project, sets the minimum version, and defines the project name and version. Ensures that option() calls in subdirectories respect normal variables set in the parent scope. ```cmake cmake_minimum_required(VERSION 3.26...3.29) project(${SKBUILD_PROJECT_NAME} LANGUAGES C VERSION ${SKBUILD_PROJECT_VERSION}) # Ensure that option() calls in subdirectories respect normal variables # set in this parent scope (e.g., disabling features in libdeflate). # Without this, CMake would ignore values set via set(...) and always use # the default provided in option(), which can lead to unexpected behavior. set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) option(WITH_SYSTEM_DEFLATE "Use system provided deflate library" OFF) ``` -------------------------------- ### get() Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieves channel samples from an MDF file, with options for filtering, raster interpolation, and data format. ```APIDOC ## get(name: str | None = None, group: int | None = None, index: int | None = None, raster: float | str | ndarray[tuple[Any, ...], dtype[Any]] | None = None, samples_only: Literal[False] = False, data: tuple[bytes, int, int | None] | None = None, raw: bool = False, ignore_invalidation_bits: bool = False, record_offset: int = 0, record_count: int | None = None, skip_channel_validation: bool = False) -> Signal | tuple[ndarray[tuple[Any, ...], dtype[Any]], None] ### Description Get channel samples. The channel can be specified in two ways: * Using the first positional argument `name`. * If there are multiple occurrences for this channel, then the `group` and `index` arguments can be used to select a specific group. * If there are multiple occurrences for this channel and either the `group` or `index` arguments is None, then a warning is issued. * Using the group number (keyword argument `group`) and the channel number (keyword argument `index`). Use `info` method for group and channel numbers. If the `raster` keyword argument is not None, the output is interpolated accordingly. ### Method GET (Implied, as data is being retrieved) ### Endpoint N/A (Object method) ### Parameters #### Path Parameters None #### Query Parameters - **name** (str | None) - Optional - Name of channel. - **group** (int | None) - Optional - 0-based group index. - **index** (int | None) - Optional - 0-based channel index. - **raster** (float | str | ndarray[tuple[Any, ...], dtype[Any]] | None) - Optional - Time raster in seconds. - **samples_only** (bool) - Optional - If True, return only the channel samples as np.ndarray; if False, return a `Signal` object. Defaults to False. - **data** (tuple[bytes, int, int | None] | None) - Optional - Prevent redundant data read by providing the raw data group samples. - **raw** (bool) - Optional - Return channel samples without applying the conversion rule. Defaults to False. - **ignore_invalidation_bits** (bool) - Optional - Only defined to have the same API with the MDF v4. Defaults to False. - **record_offset** (int) - Optional - If `data=None`, use this to select the record offset from which the group data should be loaded. Defaults to 0. - **record_count** (int | None) - Optional - Number of records to read; default is None and in this case all available records are used. - **skip_channel_validation** (bool) - Optional - Skip validation of channel name, group index and channel index. If True, the caller has to make sure that the `group` and `index` arguments are provided and are correct. Added in version 7.0.0. Defaults to False. ### Request Example ```python # Example for getting a Signal object # Assuming 'mdf' is an initialized MDF object and 'channel_name' is a valid channel name # signal_data = mdf.get(name='channel_name') # Example for getting only samples as numpy array # samples_array = mdf.get(name='channel_name', samples_only=True) ``` ### Response #### Success Response (200) - **res** (Signal | tuple[ndarray[tuple[Any, ...], dtype[Any]], None]) - Returns `Signal` if `samples_only=False` (default option), otherwise returns a (np.ndarray, None) tuple (for compatibility with MDF v4 class). The `Signal` samples are: * np.recarray for channels that have CDBLOCK or BYTEARRAY type channels * np.ndarray for all the rest #### Response Example ```json { "example": "Signal object or numpy array representing channel data" } ``` ``` -------------------------------- ### Create and Append Signals to MDF Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Initializes an MDF file and appends multiple signals with generated sample data. This is a setup for demonstrating signal retrieval. ```python >>> from asammdf import MDF, Signal >>> import numpy as np >>> t = np.arange(5) >>> s = np.ones(5) >>> mdf = MDF(version='4.10') >>> for i in range(4): ... sigs = [Signal(s * (i * 10 + j), t, name='Sig') for j in range(1, 4)] ... mdf.append(sigs) ``` -------------------------------- ### Get MDF Information Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieves general information about the MDF file in a dictionary format. ```APIDOC ## GET /api/mdf/info ### Description Retrieves general information about the MDF file in a dictionary format. ### Method GET ### Endpoint /api/mdf/info ### Response #### Success Response (200) - **info** (object) - A dictionary containing MDF file information. #### Response Example ```json { "info": { "version": "3.30", "file_name": "test.mdf", "channels": 3, "groups": 4 } } ``` ``` -------------------------------- ### Install Git Hooks with Pre-commit Source: https://github.com/danielhrisca/asammdf/blob/master/CONTRIBUTING.md Set up Git hooks using pre-commit to automatically run checks and formatting on code commits. This helps maintain code quality. ```bash pre-commit install --install-hooks ``` -------------------------------- ### Create and Append Signals to MDF File Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Demonstrates creating a new MDF file and appending multiple signals with the same name across different data groups. This setup is used to illustrate handling of ambiguous channel names. ```python >>> from asammdf import MDF, Signal >>> import numpy as np >>> t = np.arange(5) >>> s = np.ones(5) >>> mdf = MDF(version='3.30') >>> for i in range(4): ... sigs = [Signal(s * (i * 10 + j), t, name='Sig') for j in range(1, 4)] ... mdf.append(sigs) ``` -------------------------------- ### Get Channel Samples as Signal Object Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieves channel samples as a Signal object. Use this when you need signal metadata along with the data. ```python >>> mdf.get(name='Positive') ``` -------------------------------- ### Display Python and Library Versions Source: https://github.com/danielhrisca/asammdf/blob/master/ISSUE_TEMPLATE.md Run this snippet to display the Python version, OS platform, and installed versions of numpy and asammdf. This is useful for debugging and verifying the environment. ```python import platform from pprint import pprint import sys pprint("python=" + sys.version) pprint("os=" + platform.platform()) try: import numpy pprint("numpy=" + numpy.__version__) except ImportError: pass try: import asammdf pprint("asammdf=" + asammdf.__version__) except ImportError: pass ``` -------------------------------- ### Create and Save MDF File with Signals Source: https://github.com/danielhrisca/asammdf/blob/master/doc/examples.md Demonstrates creating an MDF version 4.10 file, appending signals, saving it, converting to version 3.10, filtering signals, and saving with compression. ```python from asammdf import MDF, Signal import numpy as np # create 3 Signal objects timestamps = np.array([0.1, 0.2, 0.3, 0.4, 0.5], dtype=np.float32) # unit8 s_uint8 = Signal(samples=np.array([0, 1, 2, 3, 4], dtype=np.uint8), timestamps=timestamps, name='Uint8_Signal', unit='u1') # int32 s_int32 = Signal(samples=np.array([-20, -10, 0, 10, 20], dtype=np.int32), timestamps=timestamps, name='Int32_Signal', unit='i4') # float64 s_float64 = Signal(samples=np.array([-20, -10, 0, 10, 20], dtype=np.float64), timestamps=timestamps, name='Float64_Signal', unit='f8') # create empty MDf version 4.00 file with MDF(version='4.10') as mdf4: # append the 3 signals to the new file signals = [s_uint8, s_int32, s_float64] mdf4.append(signals, comment='Created by Python') # save new file mdf4.save('my_new_file.mf4', overwrite=True) # convert new file to mdf version 3.10 mdf3 = mdf4.convert(version='3.10') print(mdf3.version) # get the float signal sig = mdf3.get('Float64_Signal') print(sig) # cut measurement from 0.3s to end of measurement mdf4_cut = mdf4.cut(start=0.3) mdf4_cut.get('Float64_Signal').plot() # cut measurement from start of measurement to 0.4s mdf4_cut = mdf4.cut(stop=0.45) mdf4_cut.get('Float64_Signal').plot() # filter some signals from the file mdf4 = mdf4.filter(['Int32_Signal', 'Uint8_Signal']) # save using zipped transpose deflate blocks mdf4.save('out.mf4', compression=2, overwrite=True) ``` -------------------------------- ### Create and load MDF objects Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Demonstrates various ways to instantiate the MDF class, including creating a new object with a specified version, loading from a file path, from in-memory bytes, or from compressed archives. ```python mdf = MDF(version='3.30') # new MDF object with version 3.30 ``` ```python mdf = MDF('path/to/file.mf4') # MDF loaded from file ``` ```python mdf = MDF(BytesIO(data)) # MDF from file contents ``` ```python mdf = MDF(zipfile.ZipFile('data.zip')) # MDF creating using the first valid MDF from archive ``` ```python mdf = MDF(bz2.BZ2File('path/to/data.bz2', 'rb')) # MDF from bz2 object ``` ```python mdf = MDF(gzip.GzipFile('path/to/data.gzip', 'rb')) # MDF from gzip object ``` -------------------------------- ### Create and Access TextBlock Source: https://github.com/danielhrisca/asammdf/blob/master/doc/v2v3blocks.md Demonstrates how to create a TextBlock instance with initial text and access its content. The text is stored as bytes, with null termination. ```python >>> tx1 = TextBlock(text='VehicleSpeed') >>> tx1['text'] b'VehicleSpeed\x00' ``` -------------------------------- ### Instantiate and Use ChannelGroup Source: https://github.com/danielhrisca/asammdf/blob/master/doc/v2v3blocks.md Shows how to create a ChannelGroup object by opening an MDF file and providing the stream and address. It also demonstrates creating a ChannelGroup with sample_bytes_nr and accessing its address and ID. ```python >>> with open('test.mdf', 'rb') as mdf: ... cg1 = ChannelGroup(stream=mdf, address=0xBA52) >>> cg2 = ChannelGroup(sample_bytes_nr=32) >>> hex(cg1.address) 0xBA52 >>> cg1['id'] b'CG' ``` -------------------------------- ### Cut Signal Excluding End Points Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Cut a signal between specified start and stop timestamps, excluding the exact start and stop timestamps if they do not exist in the original data. Uses default interpolation for intermediate values. ```python >>> new_sig = old_sig.cut(1.0, 10.5, include_ends=False) >>> new_sig.timestamps[0], new_sig.timestamps[-1] (1.03, 10.48) ``` -------------------------------- ### Instantiate and Use ChannelConversion Source: https://github.com/danielhrisca/asammdf/blob/master/doc/v2v3blocks.md Demonstrates how to open an MDF file and create a ChannelConversion object using the stream and address. Also shows creating a ChannelConversion object with a conversion type and accessing its properties. ```python >>> with open('test.mdf', 'rb') as mdf: ... cc1 = ChannelConversion(stream=mdf, address=0xBA52) >>> cc2 = ChannelConversion(conversion_type=0) >>> cc1['b'], cc1['a'] 0, 100.0 ``` -------------------------------- ### Get Channel Name Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieves the name of a channel given its group and index. ```APIDOC ## GET /api/mdf/channel/name ### Description Retrieves the name of a channel given its group and index. ### Method GET ### Endpoint /api/mdf/channel/name ### Parameters #### Query Parameters - **group** (integer) - Required - 0-based group index. - **index** (integer) - Required - 0-based channel index. ### Response #### Success Response (200) - **name** (string) - The name of the specified channel. #### Response Example ```json { "name": "Sig" } ``` ``` -------------------------------- ### Create and Append Signals to MDF Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Demonstrates how to create Signal objects with sample data, timestamps, units, and names, then append them to a new MDF file. ```python >>> from asammdf import MDF, Signal >>> import numpy as np >>> s1 = np.array([1, 2, 3, 4, 5]) >>> s2 = np.array([-1, -2, -3, -4, -5]) >>> s3 = np.array([0.1, 0.04, 0.09, 0.16, 0.25]) >>> t = np.array([0.001, 0.002, 0.003, 0.004, 0.005]) >>> s1 = Signal(samples=s1, timestamps=t, unit='+', name='Positive') >>> s2 = Signal(samples=s2, timestamps=t, unit='-', name='Negative') >>> s3 = Signal(samples=s3, timestamps=t, unit='flts', name='Floats') >>> mdf = MDF(version='4.10') >>> mdf.append([s1, s2, s3], comment='created by asammdf') >>> t = np.array([0.006, 0.007, 0.008, 0.009, 0.010]) ``` -------------------------------- ### Basic MDF File Operations Source: https://github.com/danielhrisca/asammdf/blob/master/README.md Demonstrates loading an MDF file, retrieving a specific signal, plotting it, and filtering/cutting the measurement for specific signals and time intervals. Also shows conversion to a different MDF version and saving the result. ```python from asammdf import MDF mdf = MDF('sample.mdf') speed = mdf.get('WheelSpeed') speed.plot() important_signals = ['WheelSpeed', 'VehicleSpeed', 'VehicleAcceleration'] # get short measurement with a subset of channels from 10s to 12s short = mdf.filter(important_signals).cut(start=10, stop=12) # convert to version 4.10 and save to disk short.convert('4.10').save('important signals.mf4') # plot some channels from a huge file efficient = MDF('huge.mf4') for signal in efficient.select(['Sensor1', 'Voltage3']): signal.plot() ``` -------------------------------- ### Instantiate and Access Channel Properties Source: https://github.com/danielhrisca/asammdf/blob/master/doc/v2v3blocks.md Demonstrates how to instantiate a Channel object from a file stream or as a new object, and how to access its properties like name and ID. ```python with open('test.mdf', 'rb') as mdf: ch1 = Channel(stream=mdf, address=0xBA52) ch2 = Channel() ch1.name 'VehicleSpeed' ch1['id'] b'CN' ``` -------------------------------- ### MDF Get Group Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieves a channel group from an MDF object as a pandas DataFrame. ```APIDOC ## POST /api/mdf/get_group ### Description Retrieves a specific channel group from an MDF object and returns it as a pandas DataFrame. Handles potential multiple occurrences of channel names by appending counters. ### Method POST ### Endpoint /api/mdf/get_group ### Parameters #### Request Body - **mdf_object** (object) - Required - The MDF object from which to retrieve the group. - **index** (integer) - Required - The index of the channel group to retrieve. - **raster** (float | string | object) - Optional - Raster for resampling the group data. - **time_from_zero** (boolean) - Optional - If true, timestamps are relative to the start of the file. Defaults to true. - **empty_channels** (string) - Optional - How to handle empty channels ('skip' or 'zeros'). Defaults to 'skip'. - **use_display_names** (boolean) - Optional - If true, display names are used for channels. Defaults to false. - **time_as_date** (boolean) - Optional - If true, time is returned as datetime objects. Defaults to false. - **reduce_memory_usage** (boolean) - Optional - If true, memory usage is reduced. Defaults to false. - **raw** (boolean | object) - Optional - If true, raw channel data is returned. Can be a boolean or a dictionary for specific channels. Defaults to false. - **ignore_value2text_conversions** (boolean) - Optional - If true, value to text conversions are ignored. Defaults to false. - **only_basenames** (boolean) - Optional - If true, only base channel names are returned. Defaults to false. ### Request Example ```json { "mdf_object": { ... }, "index": 0, "raster": "10ms", "time_from_zero": true, "use_display_names": true } ``` ### Response #### Success Response (200) - **dataframe** (object) - A pandas DataFrame representing the channel group. #### Response Example ```json { "dataframe": { ... } } ``` ``` -------------------------------- ### Get Channel Unit Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieves the unit of a specific channel. The channel can be identified by name, or by group and index. ```APIDOC ## GET /api/mdf/channel/unit ### Description Retrieves the unit of a specific channel. The channel can be identified by name, or by group and index. ### Method GET ### Endpoint /api/mdf/channel/unit ### Parameters #### Query Parameters - **name** (string) - Optional - Name of the channel. - **group** (integer) - Optional - 0-based group index. - **index** (integer) - Optional - 0-based channel index. ### Response #### Success Response (200) - **unit** (string) - The unit string for the specified channel. #### Response Example ```json { "unit": "V" } ``` ``` -------------------------------- ### Get Invalidation Bits Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieves the invalidation indexes for channels within a specified group, given a fragment of data. ```APIDOC ## GET /api/get_invalidation_bits ### Description Get invalidation indexes of the channels in the given group. ### Method GET ### Endpoint /api/get_invalidation_bits ### Parameters #### Query Parameters - **group_index** (int) - Required - Group index. - **pos_invalidation_bit** (int) - Required - Channel invalidation bit position. - **fragment** (Fragment) - Required - Data bytes as a Fragment. - **one_piece** (bool) - Optional - onley one piece was given in the get call. Defaults to False. ### Response #### Success Response (200) - **invalidation_bits** (InvalidationArray | None) - Iterable of valid channel indexes; if all are valid `None` is returned. #### Response Example ```json { "invalidation_bits": "[1, 2, 3]" } ``` ``` -------------------------------- ### Generate MF4 Demo File with Various Conversions Source: https://github.com/danielhrisca/asammdf/blob/master/doc/examples.md Illustrates generating an MDF file with signals that have no conversion, linear conversion, and algebraic conversion. Requires numpy and asammdf. ```python from asammdf import MDF, SUPPORTED_VERSIONS, Signal import numpy as np cycles = 100 sigs = [] mdf = MDF() t = np.arange(cycles, dtype=np.float64) # no conversion sig = Signal( np.ones(cycles, dtype=np.uint64), t, name='Channel_no_conversion', unit='s', conversion=None, comment='Unsigned 64 bit channel {}', ) sigs.append(sig) # linear conversion = { 'a': 2, 'b': -0.5, } sig = Signal( np.ones(cycles, dtype=np.int64), t, name='Channel_linear_conversion', unit='Nm', conversion=conversion, comment='Signed 64bit channel with linear conversion', ) sigs.append(sig) # algebraic conversion = { 'formula': '2 * sin(X)', } sig = Signal( np.arange(cycles, dtype=np.int32) / 100.0, t, name='Channel_algebraic', unit='eV', conversion=conversion, comment='Sinus channel with algebraic conversion', ) sigs.append(sig) ``` -------------------------------- ### Get Channel Comment Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieves the comment associated with a specific channel. The channel can be identified by name, or by group and index. ```APIDOC ## GET /api/mdf/channel/comment ### Description Retrieves the comment associated with a specific channel. The channel can be identified by name, or by group and index. ### Method GET ### Endpoint /api/mdf/channel/comment ### Parameters #### Query Parameters - **name** (string) - Optional - Name of the channel. - **group** (integer) - Optional - 0-based group index. - **index** (integer) - Optional - 0-based channel index. ### Response #### Success Response (200) - **comment** (string) - The comment string for the specified channel. #### Response Example ```json { "comment": "This is a channel comment." } ``` ``` -------------------------------- ### Python Function Calling Another Function Source: https://github.com/danielhrisca/asammdf/blob/master/doc/functions_manager.md This example demonstrates how user-defined functions can call each other. Function2 calls Function1, showcasing cross-referencing capabilities. ```python def Function1(a=0, t=0): if a > 5: return 1 else: return 0 " Function2 can call Function 1" def Function2(b=1, c=7, t=0): if b != 0: return Function1(c) else: return c / 2 ``` -------------------------------- ### Create and Extend MDF File Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Demonstrates creating a new MDF file and extending it with signals. This is useful for appending new data to an existing or newly created MDF file. Ensure signals are created with appropriate data types and timestamps. ```python >>> from asammdf import MDF, Signal >>> import numpy as np >>> s1 = np.array([1, 2, 3, 4, 5]) >>> s2 = np.array([-1, -2, -3, -4, -5]) >>> s3 = np.array([0.1, 0.04, 0.09, 0.16, 0.25]) >>> t = np.array([0.001, 0.002, 0.003, 0.004, 0.005]) >>> s1 = Signal(samples=s1, timestamps=t, unit='+', name='Positive') >>> s2 = Signal(samples=s2, timestamps=t, unit='-', name='Negative') >>> s3 = Signal(samples=s3, timestamps=t, unit='flts', name='Floats') >>> mdf = MDF(version='3.30') >>> mdf.append([s1, s2, s3], comment='created by asammdf') >>> t = np.array([0.006, 0.007, 0.008, 0.009, 0.010]) >>> mdf.extend(0, [(t, None), (s1.samples, None), (s2.samples, None), (s3.samples, None)]) ``` -------------------------------- ### Get Scaled Signal Values Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieve a new Signal object containing the scaled (physical) sample values. This is an alias for the `physical` method. ```python >>> # Example usage for scaled would go here >>> # scaled_sig = old_sig.scaled() ``` -------------------------------- ### Get Bus Signal Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Decodes a signal from raw bus logging data (CAN or LIN). Requires a database file (DBC or ARXML) for decoding. ```APIDOC ## GET /api/mdf/bus_signal ### Description Retrieves and decodes a signal from raw bus logging data (CAN or LIN) using an external database file. ### Method GET ### Endpoint /api/mdf/bus_signal ### Parameters #### Query Parameters - **bus** (string) - Required - The type of bus, either 'CAN' or 'LIN'. - **name** (string) - Required - The name of the signal to retrieve. - **database** (string or object) - Optional - Path to the external CAN/LIN database file (.dbc or .arxml) or a canmatrix.CanMatrix object. - **ignore_invalidation_bits** (boolean) - Optional - If True, invalidation bits are ignored. Defaults to False. - **data** (object) - Optional - The raw bus data as a Fragment object. - **raw** (boolean) - Optional - If True, returns raw channel samples without applying the conversion rule. Defaults to False. - **ignore_value2text_conversion** (boolean) - Optional - If True, returns channel samples without applying value-to-text conversion from the database. Defaults to True. ### Response #### Success Response (200) - **Signal** (object) - A Signal object containing the decoded physical values, timestamps, unit, and comment. #### Response Example ```json { "samples": [1.23, 4.56, 7.89], "timestamps": [0.01, 0.02, 0.03], "unit": "V", "comment": "Engine temperature" } ``` ``` -------------------------------- ### Get Master Channel Samples Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieves master channel samples for a given group index. Allows specifying record offset and count. ```APIDOC ## GET /api/mdf/master/samples ### Description Retrieves master channel samples for a given group index. Allows specifying record offset and count. ### Method GET ### Endpoint /api/mdf/master/samples ### Parameters #### Query Parameters - **index** (integer) - Required - Group index. - **record_offset** (integer) - Optional - Record offset from which the group data should be loaded. Defaults to 0. - **record_count** (integer) - Optional - Number of records to read. Defaults to all available records. ### Response #### Success Response (200) - **samples** (array) - Array of master channel samples. #### Response Example ```json { "samples": [0.0, 1.0, 2.0, 3.0, 4.0] } ``` ``` -------------------------------- ### Create and Append Signals to MDF Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Demonstrates how to create an empty MDF object and append Signal objects to it. Requires importing MDF and Signal from asammdf, and numpy. ```python >>> from asammdf import MDF, Signal >>> import numpy as np >>> mdf = MDF() >>> sig = Signal(name='S1', samples=[1, 2, 3, 4], timestamps=[1, 2, 3, 4]) >>> mdf.append(sig) >>> sig = Signal(name='S2', samples=[1, 2, 3, 4], timestamps=[1.1, 3.5, 3.7, 3.9]) >>> mdf.append(sig) ``` -------------------------------- ### Get MDF File Version Source: https://github.com/danielhrisca/asammdf/blob/master/ISSUE_TEMPLATE.md Use this code to retrieve the version of an MDF file. This is helpful for understanding compatibility or specific file characteristics. ```python print(MDF(file).version) ``` -------------------------------- ### Stack Multiple MDF Files Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Demonstrates how to stack multiple MDF files into a single MDF object. Supports various file types including standard files, BytesIO, zip, bz2, and gzip compressed files. The `sync` parameter can align files by measurement start time. ```python >>> stacked = MDF.stack( [ 'path/to/file.mf4', MDF(BytesIO(data)), MDF(zipfile.ZipFile('data.zip')), MDF(bz2.BZ2File('path/to/data.bz2', 'rb')), MDF(gzip.GzipFile('path/to/data.gzip', 'rb')), ], version='4.00', sync=False, ) ``` -------------------------------- ### Resample Channels Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Resamples all channels in an MDF file using a specified raster. This function allows for time-based resampling and can adjust timestamps to start from zero. ```APIDOC ## POST /api/mdf/resample ### Description Resample all channels using the given raster. See [`configure`](#asammdf.mdf.MDF.configure) to select the interpolation method for integer and float channels. ### Method POST ### Endpoint /api/mdf/resample ### Parameters #### Query Parameters - **raster** (float | str | ndarray) - Required - New raster that can be: * a float step value * a channel name whose timestamps will be used as raster (starting with asammdf 5.5.0) * an array (starting with asammdf 5.5.0) - **version** (str | None) - Optional - New MDF file version from (‘2.00’, ‘2.10’, ‘2.14’, ‘3.00’, ‘3.10’, ‘3.20’, ‘3.30’, ‘4.00’, ‘4.10’, ‘4.11’, ‘4.20’); default is None and in this case the original file version is used. - **time_from_zero** (bool) - Optional - Start timestamps from 0s in the resampled measurement. - **progress** (Callable | Any | None) - Optional - Progress callback function. ### Response #### Success Response (200) - **mdf** (MDF) - New [`MDF`](#asammdf.mdf.MDF) object with resampled channels. #### Response Example ```json { "mdf": "" } ``` ``` -------------------------------- ### Create and Activate Virtual Environment Source: https://github.com/danielhrisca/asammdf/blob/master/CONTRIBUTING.md Use these commands to create and activate a Python virtual environment for development. This isolates project dependencies. ```bash python -m venv .venv ``` ```bash source .venv/bin/activate ``` ```bash .venv\Scripts\activate.bat ``` -------------------------------- ### Get LIN Signal Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieves a LIN signal from the MDF file. Supports specifying external LIN databases and various signal naming conventions. ```APIDOC ## GET /api/signals/lin ### Description Get LIN message signal. You can specify an external LIN database path or a canmatrix database object that has already been loaded from a file. The signal name can be specified in the following ways: * `LIN_Frame_.` - Example: LIN_Frame_218.FL_WheelSpeed * `.` - Example: Wheels.FL_WheelSpeed * `` - Example: FL_WheelSpeed #### Versionadded Added in version 6.0.0. ### Parameters #### Query Parameters - **name** (str) - Required - Signal name. - **database** (CanMatrix | str | Path | None) - Optional - Path of external LIN database file (.dbc, .arxml or .ldf) or canmatrix.CanMatrix. - **ignore_invalidation_bits** (bool) - Optional - Option to ignore invalidation bits. - **data** (Fragment | None) - Optional - Data bytes as a Fragment. - **raw** (bool) - Optional - Return channel samples without applying the conversion rule. - **ignore_value2text_conversion** (bool) - Optional - Return channel samples without values that have a description in .dbc, .arxml or .ldf file. ### Returns #### Success Response (200) - **sig** (Signal) - Signal object with the physical values. #### Response Example ```json { "sig": "" } ``` ``` -------------------------------- ### Select Channels Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Demonstrates how to select specific channels from an MDF file using various criteria. ```APIDOC ## SELECT CHANNELS ### Description Selects channels from an MDF file based on provided criteria. Supports selecting by channel name, group and channel index, or a combination. ### Parameters #### channels - **channels** (List[str | tuple[str | None, int, int] | tuple[str, int]]) - Required - A list specifying the channels to select. Each item can be a channel name string, or a tuple containing (channel name, group index, channel index), or (channel name, group index), or (None, group index, channel index). - **record_offset** (int) - Optional - An offset in records to start reading from, useful for optimizing the retrieval of the last part of signal samples. - **raw** (bool | dict[str, bool]) - Optional - If True, returns raw channel samples. In version 8.0.0 and later, this can be a dictionary where keys are channel names and values are booleans to specify raw mode for individual channels. The key '__default__' is mandatory for specifying the default raw mode for unspecified channels. - **copy_master** (bool) - Optional - If True, creates a new timestamps array for each selected Signal. If False, uses a shared array for channels within the same channel group. - **ignore_value2text_conversions** (bool) - Optional - If True and `raw=False`, uses the raw numeric values and bypasses value to text conversions. Changed in version 5.8.0. - **record_count** (int) - Optional - The number of records to read. Defaults to None, which means all available records are used. - **validate** (bool) - Optional - If True, considers invalidation bits. Added in version 5.16.0. ### Returns - **signals** (List[Signal]) - A list of `Signal` objects corresponding to the selected channels. ### Request Example ```python >>> from asammdf import MDF, Signal >>> import numpy as np >>> t = np.arange(5) >>> s = np.ones(5) >>> mdf = MDF() >>> mdf.configure(raise_on_multiple_occurrences=False) >>> for i in range(4): ... sigs = [Signal(s * (i * 10 + j), t, name='SIG') for j in range(1, 4)] ... mdf.append(sigs) >>> mdf.select(['SIG', ('SIG', 3, 1), ['SIG', 2], (None, 1, 2)]) ``` ``` -------------------------------- ### Get CAN Signal Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieves a specific CAN signal from the measurement data. Supports various naming conventions for signals and allows specifying an external CAN database for interpretation. ```APIDOC ## GET /api/get_can_signal ### Description Get CAN message signal. You can specify an external CAN database path or a canmatrix database object that has already been loaded from a file. The signal name can be specified in the following ways: * `CAN..` - the `ID` value starts from 1 and must match the ID found in the measurement (the source CAN bus ID). Example: CAN1.Wheels.FL_WheelSpeed * `CAN.CAN_DataFrame_.` - the `ID` value starts from 1 and the `MESSAGE_ID` is the decimal message ID as found in the database. Example: CAN1.CAN_DataFrame_218.FL_WheelSpeed * `.` - in this case the first occurrence of the message name and signal are returned (the same message could be found on multiple CAN buses; for example on CAN1 and CAN3). Example: Wheels.FL_WheelSpeed * `CAN_DataFrame_.` - in this case the first occurrence of the message name and signal are returned (the same message could be found on multiple CAN buses; for example on CAN1 and CAN3). Example: CAN_DataFrame_218.FL_WheelSpeed * `` - in this case the first occurrence of the signal name is returned (the same signal name could be found in multiple messages and on multiple CAN buses). Example: FL_WheelSpeed ### Method GET ### Endpoint /api/get_can_signal ### Parameters #### Query Parameters - **name** (str) - Required - Signal name. - **database** (CanMatrix | str | PathLike[str] | None) - Optional - Path of external CAN database file (.dbc or .arxml) or canmatrix.CanMatrix. Changed in version 6.0.0: `db` and `database` arguments were merged into this single argument. - **ignore_invalidation_bits** (bool) - Optional - Option to ignore invalidation bits. Defaults to False. - **data** (Fragment | None) - Optional - Data bytes as a Fragment. - **raw** (bool) - Optional - Return channel samples without applying the conversion rule. Defaults to False. - **ignore_value2text_conversion** (bool) - Optional - Return channel samples without values that have a description in .dbc or .arxml file. Defaults to True. ### Response #### Success Response (200) - **sig** (Signal) - Signal object with the physical values. #### Response Example ```json { "sig": "" } ``` ``` -------------------------------- ### Create and Append Signals to MDF Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md This snippet demonstrates how to create an empty MDF object, configure it, and append multiple signals to it. It's useful for building MDF files programmatically. ```python >>> from asammdf import MDF, Signal >>> import numpy as np >>> t = np.arange(5) >>> s = np.ones(5) >>> mdf = MDF() >>> mdf.configure(raise_on_multiple_occurrences=False) >>> for i in range(4): ... sigs = [Signal(s * (i * 10 + j), t, name='SIG') for j in range(1, 4)] ... mdf.append(sigs) ``` -------------------------------- ### Get Signal from MDF File Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md Retrieves a signal from an MDF file. Handles cases with multiple channels of the same name by allowing specification of group and index. ```APIDOC ## GET /api/mdf/signal ### Description Retrieves a signal from an MDF file. If multiple channels have the same name, you can specify the group and index to select the desired channel. ### Method GET ### Endpoint /api/mdf/signal ### Parameters #### Query Parameters - **name** (string) - Required - The name of the signal to retrieve. Can be None if group and index are provided. - **group** (integer) - Optional - The group index of the signal. - **index** (integer) - Optional - The channel index within the group. - **samples_only** (boolean) - Optional - If True, returns only samples and invalidation bits. Defaults to False. - **ignore_invalidation_bits** (boolean) - Optional - If True, invalidation bits are ignored. Defaults to False. - **raise_on_multiple_occurrences** (boolean) - Optional - If True, raises an exception if multiple channels match the criteria. Defaults to True. ### Response #### Success Response (200) - **Signal** (object) - If `samples_only` is False, returns a Signal object containing samples, timestamps, unit, and comment. - **tuple** (tuple) - If `samples_only` is True, returns a tuple of (np.ndarray, np.ndarray) containing samples and invalidation bits. The second element can be None if invalidation bits are not used or ignored. #### Response Example ```json { "samples": [12.0, 12.0, 12.0, 12.0, 12.0], "timestamps": [0.0, 1.0, 2.0, 3.0, 4.0], "unit": "", "comment": "" } ``` #### Error Response (404) - **MdfException** (string) - If the channel name is not found, group index is out of range, channel index is out of range, or if arguments are ambiguous for multiple occurrences and `raise_on_multiple_occurrences` is True. ``` -------------------------------- ### Use MDF as a context manager Source: https://github.com/danielhrisca/asammdf/blob/master/doc/api.md It is best practice to use the MDF class as a context manager to ensure all resources are released correctly, especially in case of exceptions. ```python with MDF(r'test.mdf') as mdf_file: # do something ```