nspyre.data

Subpackages

Submodules

Package Contents

Classes

DataSink

For sinking data from the DataServer.

DataSource

For sourcing data to the DataServer.

StreamingList

List-like object that can be streamed efficiently through the DataServer.

Functions

load_json(filename)

Load data from a JSON file.

load_pickle(filename)

Load data from a Python pickle file.

save_json(filename, data)

Save data to a json file.

save_pickle(filename, data)

Save data to a python pickle file.

nspyre.data.load_json(filename)

Load data from a JSON file.

Parameters:

filename (Union[str, pathlib.Path]) – File to load from.

Returns:

A Python object loaded from the file.

Return type:

Any

nspyre.data.load_pickle(filename)

Load data from a Python pickle file.

Parameters:

filename (Union[str, pathlib.Path]) – File to load from.

Returns:

A Python object loaded from the file.

Return type:

Any

nspyre.data.save_json(filename, data)

Save data to a json file.

Parameters:
  • filename (Union[str, pathlib.Path]) – File to save to.

  • data (Any) – Python object to save.

nspyre.data.save_pickle(filename, data)

Save data to a python pickle file.

Parameters:
  • filename (Union[str, pathlib.Path]) – File to save to.

  • data (Any) – Python object to save.

class nspyre.data.DataSink(name, addr='localhost', port=DATASERV_PORT, auto_reconnect=False)

For sinking data from the DataServer. data can be used to directly access the python object pushed by the source. E.g.:

First, start the data server:

$ nspyre-dataserv
from nspyre import DataSink, DataSource

with DataSource('my_dataset') as src:
    src.push('Data!')

with DataSink('my_dataset') as sink:
    sink.pop()
    print(sink.data)

Alternatively, if the data pushed by the source is a dictionary, its values can be accessed as if they were attributes of the sink, e.g.:

from nspyre import DataSink, DataSource

with DataSource('my_dataset') as src:
    data = {
        'some_data': 1,
        'some_other_data': 'a string'
    }
    src.push(data)

with DataSink('my_dataset') as sink:
    sink.pop()
    print(sink.some_data)
    print(sink.some_other_data)
Parameters:
  • name (str) – Name of the data set.

  • addr (str) – Network address of the data server.

  • port (int) – Port of the data server.

  • auto_reconnect (bool) – If True, automatically reconnect to the data server if it is disconnected. Otherwise raise an error if connection fails.

data: Any

The object pushed by the DataSource.

start()

Connect to the data server.

stop()

Disconnect from the data server.

pop(timeout=None)

Block waiting for an updated version of the data from the data server. Once the data is received, the internal data attribute will be updated and the function will return.

Typical usage example:

First start the data server from the console on machine A:

$ nspyre-dataserv

Run the python program on machine A implementing the experimental logic:

# machine A: "source"-side code
# running on the same machine as the data server, in the same or a
# different process

from nspyre import DataSource
import numpy as np

# connect to the data server and create a data set, or connect to an
# existing one with the same name if it was created earlier
with DataSource('my_dataset') as source:
    # do an experiment where we measure voltage of something as a
    # function of frequency
    n = 100
    frequencies = np.linspace(1e6, 100e6, n)
    voltages = np.zeros(n)

    for f in frequencies:
        signal_generator.set_frequency(f)
        voltages[i] = daq.get_voltage()
        # push most up-to-date data to the server
        source.push({'freq': frequencies, 'volts': voltages})

Then run the python program on machine B implementing the data plotting:

# machine B: "sink"-side code
# running on a different machine as the source / data server

from nspyre import DataSink

# connect to the data set on the data server
# IP of data server computer = '192.168.1.50'
with DataSink('my_dataset', '192.168.1.50') as sink:
    while True:
        # block until an updated version of the data set is available
        sink.pop():
        # sink.freq and sink.volts have been modified
        # replot the data to show the new values
        my_plot_update(sink.freq, sink.volts)
Parameters:

timeout – Time to wait for an update in seconds. Set to None to wait forever.

Raises:
  • TimeoutError – A timeout occured.

  • RuntimeError – The sink isn’t properly initialized.

class nspyre.data.DataSource(name, addr='localhost', port=DATASERV_PORT, auto_reconnect=False)

For sourcing data to the DataServer. See pop() for typical usage example.

Parameters:
  • name (str) – Name of the data set.

  • addr (str) – Network address of the data server.

  • port (int) – Port of the data server.

  • auto_reconnect (bool) – If True, automatically reconnect to the data server if it is disconnected. Otherwise raise an error if connection fails.

start()

Connect to the data server.

stop()

Disconnect from the data server.

push(data)

Push new data to the data server.

Parameters:

data – Any python object (must be pickleable) to send. Ideally, this should be a dictionary to allow for simple attribute access from the sink side like sink.my_var.

class nspyre.data.StreamingList(iterable=None)

List-like object that can be streamed efficiently through the DataServer. StreamingList is meant to act as a drop-in replacement for a python list. When this object is pushed to the data server using a call to push(), instead of sending the whole contents of StreamingList, only the differences since the last push() are sent. This allows for much higher data throughput for larger data sets.

Although StreamingList is typically able to automatically calculate the differences since the last push(), there is one situation where this is not possible: if a mutable object that is contained somewhere inside the StreamingList is modified, it cannot be detected. In this situation, the StreamingList must be manually notified that one of its items has been updated, e.g.:

import numpy as np
from nspyre import DataSource
from nspyre import StreamingList

with DataSource('my_dataset') as src:
    sl = StreamingList()
    a = np.array([1, 2, 3])
    b = np.array([4, 5, 6])
    c = np.array([7, 8, 9])

    # these StreamingList calls will automatically calculate diffs
    sl.append(a)
    sl.append(b)
    sl.append(c)

    src.push(sl)

    # here we are modifying a mutable object inside of the StreamingList,
    # which it cannot detect
    a[1] = 10

    # we can manually tell the StreamingList that its object 'a' was modified
    sl.updated_item(0)

    src.push(sl)
Parameters:

iterable – iterable object to initialize the contents of the list with, e.g. sl = StreamingList([1, 2, 3]).

updated_item(idx)

The item at the given index was modified, and, therefore, its cached value is no longer valid and must be updated.

Parameters:

idx – index that was modified

insert(idx, val, register_diff=True)

See docs for Python list.

remove(val)

See docs for Python list.

pop(idx)

See docs for Python list.

append(val)

See docs for Python list.

extend(val)

See docs for Python list.

clear()

See docs for Python list.

sort(*args, **kwargs)

See docs for Python list.

reverse()

See docs for Python list.

copy()

See docs for Python list.