Syncopy Data Basics#

Syncopy utilizes a simple data format based on HDF5 and JSON (see Reading and Writing Data for details). These formats were chosen for their ubiquity as they can be handled well in virtually all popular programming languages, and for allowing streaming, parallel access enabling computing on parallel architectures.

Loading and Saving Syncopy (*.spy) Data#

Reading and writing data with Syncopy

syncopy.load(filename[, tag, dataclass, ...])

Load Syncopy data object(s) from disk

syncopy.save(out[, container, tag, ...])

Save Syncopy data object to disk

Functions for Inspecting/Editing Syncopy Data Objects#

Defining trials, data selection and NumPy ndarray interface

syncopy.definetrial(obj[, trialdefinition, ...])

(Re-)define trials of a Syncopy data object

syncopy.selectdata(data[, trials, channel, ...])

Create a new Syncopy object from a selection

syncopy.show(data[, squeeze])

Show (partial) contents of Syncopy object

Plotting Functions#

syncopy.singlepanelplot(data, **show_kwargs)

Plot Syncopy data in a single panel

syncopy.multipanelplot(data, **show_kwargs)

Plot Syncopy data in multiple panels

Hint

The Selections section details how singlepanelplot() and show() all work based on the same selectdata() API.

Importing Data into Syncopy#

Importing Data from different file formats into Syncopy#

Currently, Syncopy supports importing data from FieldTrip raw data format, from NWB and TDT:

syncopy.io.load_ft_raw(filename[, ...])

Imports raw time-series data from Field Trip into potentially multiple AnalogData objects, one for each structure found within the MAT-file.

syncopy.io.load_nwb(filename[, memuse, ...])

Read contents of NWB files

syncopy.io.load_tdt(data_path[, start_code, ...])

Imports TDT time series data and meta-information into a single AnalogData object.

Importing Data from NumPy#

If you have an electrical time series as a ndarray and want to import it into Syncopy, you can initialize an AnalogData object directly:

import syncopy as spy
import numpy as np

# 3 channel surrogate data
np_data = np.random.randn(10_000, 3)

# initialize AnalogData
spy_data = spy.AnalogData(np_data, samplerate=1000)

Without an explicit trialdefinition the default all-to-all definition is used, meaning all data is merged into a single trial. Setting a trialdefinition requires building a M x 3 matrix, with M being the number of trials, and each row containing [start, stop, offset] in samples:

spy_data.trialdefinition = np.array([[0, 3000, 1000], [3000, 6000, 1000]])

With this we have 2 trials, each 3000 samples long starting at -1 seconds.

syncopy.AnalogData([data, filename, ...])

Multi-channel, uniformly-sampled, analog (real float) data

Creating Synthetic Example Data#

Syncopy contains the synthdata module, which can be used to create synthetic data for testing and demonstration purposes.

syncopy.synthdata

Exporting Data from Syncopy to NWB#

Syncopy supports export of data to NWB format for objects of type AnalogData, TimeLockData and SpikeData.

syncopy.AnalogData.save_nwb(outpath[, ...])

Save AnalogData in Neurodata Without Borders (NWB) file format.

syncopy.TimeLockData.save_nwb(outpath[, ...])

Save TimeLockData in Neurodata Without Borders (NWB) file format.

syncopy.SpikeData.save_nwb(outpath[, ...])

Save SpikeData in Neurodata Without Borders (NWB) file format.

Here is a little example:

import syncopy as spy

raw_data = spy.synthdata.red_noise(alpha=0.9)

# some processing, bandpass filter and (here meaningless) phase extraction
processed_data = spy.preprocessing(raw_data, filter_type='bp', freq=[35, 40], hilbert='angle')

# save raw data to NWB
nwb_path = 'test.nwb'
nwbfile = raw_data.save_nwb(nwb_path)

# save processed data into same NWB file
processed_data.save_nwb(nwb_path, nwbfile=nwbfile, is_raw=False)

Note that NWB is a very general container format, and thus loading an NWB container created in one software package into the internal data structures used by another software package requires some interpretation of the fields, which users many need to do manually. One can inspect NWB files online using tools like the NWB Explorer.

Data exchange and interoperability between Syncopy and MNE Python#

The MNE Python package is a popular open-source package for analyzing electrophysiological data. Syncopy comes with data conversion functions for the MNE data classes like, so data can be exchanged more easily between the two packages. In order to use these functions, users will need to manually install MNE into the syncopy environment.

The following conversion functions are available:

syncopy.raw_adata_to_mne_raw(adata)

Convert raw spy.AnalogData (single-trial data) to an MNE Python RawArray.

syncopy.raw_mne_to_adata(ar)

Convert MNE python mne.io.RawArray to spy.AnalogData (single-trial data).

syncopy.tldata_to_mne_epochs(tldata)

Convert Syncopy timelocked data to MNE Python mne.EpochsArray.

syncopy.mne_epochs_to_tldata(ea)

Convert MNE EpochsArray to time-locked Syncopy AnalogData instance.

Here is an example of how to import data from MNE Python into Syncopy. Once more, make sure you have mne installed.:

import syncopy as spy
import mne

# Load data in MNE Python
sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = os.path.join(
  sample_data_folder, "MEG", "sample", "sample_audvis_raw.fif"
)
mne_data = mne.io.read_raw_fif(sample_data_raw_file, preload=True)

# Convert to Syncopy AnalogData
spy_data = spy.io.mne_conv.raw_mne_to_adata(mne_data)

# save to Syncopy HDF5 format
spy_data.save('sample_audvis_raw.spy')