Skip to main content

Skope NYOX SDK. Contains data reader for skope-fx session files and protocol definitions to directly connect to the NYOX controller

Project description

NYOX SDK for Python

A Python SDK for reading Skope NYOX session files and communicating with NYOX controllers.

Features

  • Data Reader: Read and parse skope-fx session files (.h5 format) to access complete system configuration, field models, and scan data
  • Protocol Client: Direct communication interface with NYOX controllers
  • Cross-platform Support: Works on Windows and Linux with compiled extension modules for performance

Requirements

  • Python 3.10 - 3.13
  • h5py (HDF5 support)
  • numpy
  • cachetools
  • jsonschema

Installation

pip install nyox-sdk

Quick Start

Reading Session Data

Please refer to the User Manual for detailed instructions on using the data reader.

from nyox_sdk import reader

# Load a session file
session = reader.Session("path/to/session.h5")

# Access system configuration
print(session.system_config.nucleus)
print(session.system_config.B0)

# Read scans
for scan in session.scans:
    print(f"Scan ID: {scan.id}")

Protocol Client

from nyox_sdk.protocol import NyoxClient

# Connect and send commands to controller
client = NyoxClient()

Examples Usage

Reader

# Example of how to use the reader module to access session and scan data from a session file created by skope-fx.

from nyox_sdk import reader

# load and print session
session_file = "Path/To/SessionFile.h5"
session = reader.Session(session_file)
print(session)

# iterate through scans
for scan in session.scans:
    nr_datapoints = f"{scan.nr_samples * scan.nr_channels * scan.nr_acquisitions:,}"
    print(str(scan.scan_nr) + " - " + nr_datapoints)

# select a specific scan
scan = session.get_scan(3)

# get information from the scan
print(scan)
print(scan.name)
print(scan.nr_acquisitions)
print(scan.dt)

# get trigger information
trigger = scan.trigger

# accessing raw data
raw_data_0 = scan.load_raw_data(0)                  # load raw data for first acquisition only
raw_data_all = scan.raw                             # access all raw data and save it to cache
data = scan.load_raw_data(1)                        # using cached raw data -> faster access

# accessing phase data
phase_data_0 = scan.load_phase(0)                   # calculating the phase for the first acquisition only
phase_data_all = scan.phase                         # get all phase data -> this will load all raw data if not cached before

# access the trajectory data
traj_0 = scan.calculate_trajectory(0)               # calculate the trajectory for the first acquisition only
traj_all = scan.trajectory                          # calculate all trajectories and save it to cache
traj_1 = scan.calculate_trajectory(1)               # using cached trajectories -> no recalculating needed

# change the field model
field_model = scan.get_field_model()
field_model.selected_spatial_basis = [True, True, True, True]
field_model.includes_coco_terms = False
scan.set_field_model(field_model)

# reset the field model to the original
scan.reset_field_model()

Protocol Client

"""
Simple example: Connect to a NYOX system and acquire data

Edit the configuration section below to match your setup.
This script connects, acquires a short scan, and plots the data.
"""

import os
import asyncio
from nyox_sdk.protocol import NyoxClient
from nyox_sdk.protocol import protocol_json as jsp

from nyox_sdk.reader.skope_processing import skope_processing_python as spp # For data processing
spp.version()
import numpy as np 
import matplotlib.pyplot as plt

# ----------------------
# User configuration
# ----------------------
DEVICE_ADDR = "127.0.0.1"     # NYOX system IP address
DATA_FOLDER = "data/"         # Folder to save data (must exist)
BASE_NAME = "example_stream"  # Base name for output files
ACQ_DURATION = 50e-3          # Acquisition duration (seconds)
NR_ACQ = 3                    # Number of acquisitions
NR_CHANNELS = 16              # Number of channels (typically 16 for NYOX)


async def acquire_data(client: NyoxClient):
    """Acquire a scan from the NYOX system."""
    # Get default scan definition
    resp = await client.get_defaultShortScanDef()

    # modify shortScanDef according to your needs
    scan_def = jsp.parse_shortscandef(resp)
    scan_def['nrAcquisitions'] = NR_ACQ
    scan_def['acqDuration'] = ACQ_DURATION

    # Start scan
    await client.start_scan(scan_def)
    await client.wait_for_stream_done()
    print("Acquisition complete.")
    await client.disconnect()

async def process_data(client: NyoxClient, payload: bytes):
    """Example of a custom data processing function that can be passed to NyoxClient."""
    # Get information from scan header
    header = client.scan_header
    # Convert raw bytes to numpy array
    raw_data = np.frombuffer(payload, dtype=np.uint32)
    try:
        raw_data = raw_data.reshape(-1, NR_CHANNELS)
        raw_data = raw_data.transpose()  # Shape: (NR_CHANNELS, samples)
    except Exception as e:
        print("Error reshaping data:", e)
        return
    print("Received data shape:", raw_data.shape)

def do_plot(data: np.ndarray):
    fig, ax = plt.subplots()
    for aq in range (data.shape[0]): 
        for ch in range(data.shape[1]):
            ax.plot(data[aq,ch,:], label=f"channel {ch} - acq {aq}")
    ax.set(xlabel='sample#', ylabel='value (raw)',
            title='Skope data acquisition')
    plt.legend()
    plt.show()

def main():
    # Check if the data folder exists and create it if not
    if not os.path.exists(DATA_FOLDER):
        try:
            os.makedirs(DATA_FOLDER)
            print(f"Created data folder: {DATA_FOLDER}")
        except Exception as e:
            print(f"Error creating data folder: {e}")
            return

    # Connect to NYOX system and acquire data
    print("Connecting to NYOX system at:", DEVICE_ADDR)
    try:
        client = NyoxClient(DEVICE_ADDR, acquire_data, outfile_prefix=os.path.join(DATA_FOLDER, BASE_NAME), data_callback=process_data)
        asyncio.run(client.run())
    except Exception as e:
        print("Error during acquisition:", e)
        return

    # Load and print shape of acquired data
    import numpy as np
    data_path = os.path.join(DATA_FOLDER, f"{BASE_NAME}-0000.bin")
    if not os.path.exists(data_path):
        print(f"Data file not found: {data_path}")
        return
    raw_data = np.fromfile(data_path, dtype=np.uint32)
    try:
        raw_data = raw_data.reshape(NR_ACQ, -1, NR_CHANNELS)
        raw_data = raw_data.transpose(0,2,1)  # Shape: (NR_ACQ, NR_CHANNELS, samples)
    except Exception as e:
        print("Error reshaping data:", e)
        return
    print("Data shape:", raw_data.shape)

    # Use skope_processing_python to convert raw data to magnitude and phase
    mag_data: np.ndarray = spp.pm_raw_to_magnitude(raw_data)
    phase_data: np.ndarray = spp.pm_raw_to_phase(raw_data,-1)

    do_plot(mag_data)
    do_plot(phase_data)

if __name__ == "__main__":
    main()

License

See End User License Agreement for details.

Documentation

Please refer to the User Manual for detailed instructions on using the data reader.

For more information, visit skope.swiss/software

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nyox_sdk-1.0.4.tar.gz (102.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nyox_sdk-1.0.4-py3-none-any.whl (103.5 MB view details)

Uploaded Python 3

File details

Details for the file nyox_sdk-1.0.4.tar.gz.

File metadata

  • Download URL: nyox_sdk-1.0.4.tar.gz
  • Upload date:
  • Size: 102.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for nyox_sdk-1.0.4.tar.gz
Algorithm Hash digest
SHA256 373fe16c2c1a587f1f2eea78c06bb438ac2fdd12a4cbf3573cbd4372c0013761
MD5 ab106e284455f47f29e6dcbd9a1fd187
BLAKE2b-256 44a06a29609ecbc70d32bbd41c8c04706f39d3949527db01f2bf2a26882dfec9

See more details on using hashes here.

File details

Details for the file nyox_sdk-1.0.4-py3-none-any.whl.

File metadata

  • Download URL: nyox_sdk-1.0.4-py3-none-any.whl
  • Upload date:
  • Size: 103.5 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for nyox_sdk-1.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 ba5cc52bcf5f52e2e7d0f0d2ac29c26d02963cf6ee79768ae2331239d2fc9395
MD5 ec616a7b59cc4a25a8c6fb91d26dccdd
BLAKE2b-256 6409ba8b0a052f9562d4cb12b0aa105aa135ebc20b51cce5661a531d9fb73cf1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page