neo.core provides classes for storing common electrophysiological data types. Some of these classes contain raw data, such as spike trains or analog signals, while others are containers to organize other classes (including both data classes and other container classes).
Classes from neo.io return nested data structures containing one or more class from this module.
Classes:
Main container for data.
Main container gathering all the data, whether discrete or continous, for a given recording session.
A block is not necessarily temporally homogeneous, in contrast to Segment.
Usage:
>>> from neo.core import (Block, Segment, RecordingChannelGroup,
... AnalogSignalArray)
>>> from quantities import nA, kHz
>>> import numpy as np
>>>
>>> # create a Block with 3 Segment and 2 RecordingChannelGroup objects
,,, blk = Block()
>>> for ind in range(3):
... seg = Segment(name='segment %d' % ind, index=ind)
... blk.segments.append(seg)
...
>>> for ind in range(2):
... rcg = RecordingChannelGroup(name='Array probe %d' % ind,
... channel_indexes=np.arange(64))
... blk.recordingchannelgroups.append(rcg)
...
>>> # Populate the Block with AnalogSignalArray objects
... for seg in blk.segments:
... for rcg in blk.recordingchannelgroups:
... a = AnalogSignalArray(np.random.randn(10000, 64)*nA,
... sampling_rate=10*kHz)
... rcg.analogsignalarrays.append(a)
... seg.analogsignalarrays.append(a)
name: | (str) A label for the dataset. |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
file_datetime: | (datetime) The creation date and time of the original data file. |
rec_datetime: | (datetime) The date and time of the original recording. |
index: | (int) You can use this to define an ordering of your Block. It is not used by Neo in any way. |
list_units: | descends through hierarchy and returns a list of Unit objects existing in the block. This shortcut exists because a common analysis case is analyzing all neurons that you recorded in a session. |
---|---|
list_recordingchannels: | |
descends through hierarchy and returns a list of RecordingChannel objects existing in the block. |
A container for data sharing a common time basis.
A Segment is a heterogeneous container for discrete or continous data sharing a common clock (time basis) but not necessary the same sampling rate, start or end time.
>>> from neo.core import Segment, SpikeTrain, AnalogSignal
>>> from quantities import Hz, s
>>>
>>> seg = Segment(index=5)
>>>
>>> train0 = SpikeTrain(times=[.01, 3.3, 9.3], units='sec', t_stop=10)
>>> seg.spiketrains.append(train0)
>>>
>>> train1 = SpikeTrain(times=[100.01, 103.3, 109.3], units='sec',
... t_stop=110)
>>> seg.spiketrains.append(train1)
>>>
>>> sig0 = AnalogSignal(signal=[.01, 3.3, 9.3], units='uV',
... sampling_rate=1*Hz)
>>> seg.analogsignals.append(sig0)
>>>
>>> sig1 = AnalogSignal(signal=[100.01, 103.3, 109.3], units='nA',
... sampling_period=.1*s)
>>> seg.analogsignals.append(sig1)
name: | (str) A label for the dataset. |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
file_datetime: | (datetime) The creation date and time of the original data file. |
rec_datetime: | (datetime) The date and time of the original recording |
index: | (int) You can use this to define a temporal ordering of your Segment. For instance you could use this for trial numbers. |
all_data: | (list) A list of all child objects in the Segment. |
---|
A container for multiple data channels.
Usage 1 multi Segment recording with 2 electrode array:
>>> from neo.core import (Block, Segment, RecordingChannelGroup,
... AnalogSignalArray)
>>> from quantities import nA, kHz
>>> import numpy as np
>>>
>>> # create a Block with 3 Segment and 2 RecordingChannelGroup objects
,,, blk = Block()
>>> for ind in range(3):
... seg = Segment(name='segment %d' % ind, index=ind)
... blk.segments.append(seg)
...
>>> for ind in range(2):
... rcg = RecordingChannelGroup(name='Array probe %d' % ind,
... channel_indexes=np.arange(64))
... blk.recordingchannelgroups.append(rcg)
...
>>> # Populate the Block with AnalogSignalArray objects
... for seg in blk.segments:
... for rcg in blk.recordingchannelgroups:
... a = AnalogSignalArray(np.random.randn(10000, 64)*nA,
... sampling_rate=10*kHz)
... rcg.analogsignalarrays.append(a)
... seg.analogsignalarrays.append(a)
Usage 2 grouping channel:
>>> from neo.core import (Block, RecordingChannelGroup,
... RecordingChannel)
>>> import numpy as np
>>>
>>> # Create a Block
,,, blk = Block()
>>>
>>> # Create a new RecordingChannelGroup and add it to the Block
... rcg = RecordingChannelGroup(channel_names=np.array(['ch0',
... 'ch1',
... 'ch2']))
>>> rcg.channel_indexes = np.array([0, 1, 2])
>>> blk.recordingchannelgroups.append(rcg)
>>>
>>> # Create 3 RecordingChannel objects and add them to the Block
... for ind in range(3):
... chan = RecordingChannel(index=ind)
... rcg.recordingchannels.append(chan) # <- many to many
,,, # relationship
... chan.recordingchannelgroups.append(rcg) # <- many to many
... # relationship
Usage 3 dealing with Unit objects:
>>> from neo.core import Block, RecordingChannelGroup, Unit
>>>
>>> # Create a Block
... blk = Block()
>>>
>>> # Create a new RecordingChannelGroup and add it to the Block
... rcg = RecordingChannelGroup(name='octotrode A')
>>> blk.recordingchannelgroups.append(rcg)
>>>
>>> # create several Unit objects and add them to the
>>> # RecordingChannelGroup
... for ind in range(5):
... unit = Unit(name = 'unit %d' % ind, description=
... 'after a long and hard spike sorting')
... rcg.units.append(unit)
name: | (str) A label for the dataset. |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
channel_names: | (numpy.array 1D dtype=’S’) Names for each RecordingChannel. |
channel_indexes: | |
(numpy.array 1D dtype=’i’) Index of each RecordingChannel. |
A container for recordings coming from a single data channel.
A RecordingChannel is a container for AnalogSignal and IrregularlySampledSignal`objects that come from the same logical and/or physical channel inside a :class:`Block.
Note that a RecordingChannel can belong to several RecordingChannelGroup objects.
Usage one Block with 3 Segment objects, 16 RecordingChannel objects, and 48 AnalogSignal objects:
>>> from neo.core import (Block, Segment, RecordingChannelGroup,
... RecordingChannel, AnalogSignal)
>>> from quantities import mA, Hz
>>> import numpy as np
>>>
>>> # Create a Block
... blk = Block()
>>>
>>> # Create a new RecordingChannelGroup and add it to the Block
... rcg = RecordingChannelGroup(name='all channels')
>>> blk.recordingchannelgroups.append(rcg)
>>>
>>> # Create 3 Segment and 16 RecordingChannel objects and add them to
... # the Block
... for ind in range(3):
... seg = Segment(name='segment %d' % ind, index=ind)
... blk.segments.append(seg)
...
>>> for ind in range(16):
... chan = RecordingChannel(index=ind)
... rcg.recordingchannels.append(chan) # <- many to many
... # relationship
... chan.recordingchannelgroups.append(rcg) # <- many to many
... # relationship
...
>>> # Populate the Block with AnalogSignal objects
... for seg in blk.segments:
... for chan in rcg.recordingchannels:
... sig = AnalogSignal(np.random.rand(100000)*mA,
... sampling_rate=20*Hz)
... seg.analogsignals.append(sig)
... chan.analogsignals.append(sig)
index: | (int) You can use this to order RecordingChannel objects in an way you want. |
---|
name: | (str) A label for the dataset. |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
coordinate: | (quantity array 1D (x, y, z)) Coordinates of the channel in the brain. |
A container of Spike and SpikeTrain objects from a unit.
A Unit regroups all the SpikeTrain and Spike objects that were emitted by a single spike source during a Block. A spike source is often a single neuron but doesn’t have to be. The spikes may come from different Segment objects within the Block, so this object is not contained in the usual Block/ Segment/SpikeTrain hierarchy.
A Unit is linked to RecordingChannelGroup objects from which it was detected. With tetrodes, for instance, multiple channels may record the same Unit.
Usage:
>>> from neo.core import Unit, SpikeTrain
>>>
>>> unit = Unit(name='pyramidal neuron')
>>>
>>> train0 = SpikeTrain(times=[.01, 3.3, 9.3], units='sec', t_stop=10)
>>> unit.spiketrains.append(train0)
>>>
>>> train1 = SpikeTrain(times=[100.01, 103.3, 109.3], units='sec',
... t_stop=110)
>>> unit.spiketrains.append(train1)
name: | (str) A label for the dataset. |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
channel_index: | (numpy array 1D dtype=’i’) You can use this to order Unit objects in an way you want. It can have any number of elements. AnalogSignal and AnalogSignalArray objects can be given indexes as well so related objects can be linked together. |
A continuous analog signal.
A representation of a continuous, analog signal acquired at time t_start at a certain sampling rate.
Inherits from quantities.Quantity, which in turn inherits from numpy.ndarray.
Usage:
>>> from neo.core import AnalogSignal
>>> from quantities import kHz, ms, nA, s, uV
>>> import numpy as np
>>>
>>> sig0 = AnalogSignal([1, 2, 3], sampling_rate=0.42*kHz,
... units='mV')
>>> sig1 = AnalogSignal([4, 5, 6]*nA, sampling_period=42*ms)
>>> sig2 = AnalogSignal(np.array([1.0, 2.0, 3.0]), t_start=42*ms,
... sampling_rate=0.42*kHz, units=uV)
>>> sig3 = AnalogSignal([1], units='V', day='Monday',
... sampling_period=1*s)
>>>
>>> sig3
<AnalogSignal(array([1]) * V, [0.0 s, 1.0 s], sampling rate: 1.0 1/s)>
>>> sig3.annotations['day']
'Monday'
>>> sig3[0]
array(1) * V
>>> sig3[::2]
<AnalogSignal(array([1]) * V, [0.0 s, 2.0 s], sampling rate: 0.5 1/s)>
signal: | (quantity array 1D, numpy array 1D, or list) The data itself. |
---|---|
units: | (quantity units) Required if the signal is a list or NumPy array, not if it is a Quantity |
sampling_rate: | or :sampling_period: (quantity scalar) Number of samples per unit time or interval between two samples. If both are specified, they are checked for consistency. |
name: | (str) A label for the dataset. |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
t_start: | (quantity scalar) Time when signal begins. Default: 0.0 seconds |
channel_index: | (int) You can use this to order AnalogSignal objects in an way you want. AnalogSignalArray and Unit objects can be given indexes as well so related objects can be linked together. |
dtype: | (numpy dtype or str) Override the dtype of the signal array. |
---|---|
copy: | (bool) True by default. |
sampling_rate: | (quantity scalar) Number of samples per unit time. (1/sampling_period) |
---|---|
sampling_period: | |
(quantity scalar) Interval between two samples. (1/sampling_rate) | |
duration: | (quantity scalar) Signal duration, read-only. (size * sampling_period) |
t_stop: | (quantity scalar) Time when signal ends, read-only. (t_start + duration) |
times: | (quantity 1D) The time points of each sample of the signal, read-only. (t_start + arange(shape)/sampling_rate) |
Several continuous analog signals
A representation of several continuous, analog signals that have the same duration, sampling rate and start time. Basically, it is a 2D array like AnalogSignal: dim 0 is time, dim 1 is channel index
Inherits from quantities.Quantity, which in turn inherits from numpy.ndarray.
Usage:
>>> from neo.core import AnalogSignalArray
>>> import quantities as pq
>>>
>>> sigarr = AnalogSignalArray([[1, 2, 3], [4, 5, 6]], units='V',
... sampling_rate=1*pq.Hz)
>>>
>>> sigarr
<AnalogSignalArray(array([[1, 2, 3],
[4, 5, 6]]) * mV, [0.0 s, 2.0 s], sampling rate: 1.0 Hz)>
>>> sigarr[:,1]
<AnalogSignal(array([2, 5]) * V, [0.0 s, 2.0 s],
sampling rate: 1.0 Hz)>
>>> sigarr[1, 1]
array(5) * V
signal: | (quantity array 2D, numpy array 2D, or list (data, chanel)) The data itself. |
---|---|
units: | (quantity units) Required if the signal is a list or NumPy array, not if it is a Quantity |
t_start: | (quantity scalar) Time when signal begins |
sampling_rate: | or :sampling_period: (quantity scalar) Number of samples per unit time or interval between two samples. If both are specified, they are checked for consistency. |
name: | (str) A label for the dataset. |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
channel_index: | (numpy array 1D dtype=’i’) You can use this to order the columns of the signal in any way you want. It should have the same number of elements as the signal has columns. AnalogSignal and Unit objects can be given indexes as well so related objects can be linked together. |
dtype: | (numpy dtype or str) Override the dtype of the signal array. |
---|---|
copy: | (bool) True by default. |
sampling_rate: | (quantity scalar) Number of samples per unit time. (1/sampling_period) |
---|---|
sampling_period: | |
(quantity scalar) Interval between two samples. (1/quantity scalar) | |
duration: | (Quantity) Signal duration, read-only. (size * sampling_period) |
t_stop: | (quantity scalar) Time when signal ends, read-only. (t_start + duration) |
times: | (quantity 1D) The time points of each sample of the signal, read-only. (t_start + arange(shape`[0])/:attr:`sampling_rate) |
channel_indexes: | |
(numpy array 1D dtype=’i’) The same as channel_index, read-only. |
An analog signal with samples taken at arbitrary time points.
A representation of a continuous, analog signal acquired at time t_start with a varying sampling interval.
Usage:
>>> from neo.core import IrregularlySampledSignal
>>> from quantities import s, nA
>>>
>>> irsig0 = IrregularlySampledSignal([0.0, 1.23, 6.78], [1, 2, 3],
... units='mV', time_units='ms')
>>> irsig1 = IrregularlySampledSignal([0.01, 0.03, 0.12]*s,
... [4, 5, 6]*nA)
times: | (quantity array 1D, numpy array 1D, or list) The data itself. |
---|---|
signal: | (quantity array 1D, numpy array 1D, or list) The time of each data point. Must have the same size as times. |
units: | (quantity units) Required if the signal is a list or NumPy array, not if it is a Quantity. |
time_units: | (quantity units) Required if :attr`times` is a list or NumPy array, not if it is a Quantity. |
name: | (str) A label for the dataset |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
dtype: | (numpy dtype or str) Override the dtype of the signal array. (times are always floats). |
---|---|
copy: | (bool) True by default. |
sampling_intervals: | |
---|---|
(quantity array 1D) Interval between each adjacent pair of samples. (times[1:] - :attr:`times`[:-1]) | |
duration: | (quantity scalar) Signal duration, read-only. (:attr:`times`[-1] - :attr:`times`[0]) |
t_start: | (quantity scalar) Time when signal begins, read-only. (:attr:`times`[0]) |
t_stop: | (quantity scalar) Time when signal ends, read-only. (:attr:`times`[-1]) |
An event occuring at a particular point in time.
Useful for managing trigger, stimulus, comment, etc.
Usage:
>>> from neo.core import Event
>>> from quantities import s
>>>
>>> evt = Event(50*s, label='trigger')
>>>
>>> evt.time
array(50.0) * s
>>> evt.label
'trigger'
time: | (quantity scalar) The time of the event. |
---|---|
label: | (str) Name or label for the event. |
name: | (str) A label for the dataset. |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
Array of events. Introduced for performance reasons.
An EventArray is prefered to a list of Event objects.
Usage:
>>> from neo.core import EventArray
>>> from quantities import s
>>> import numpy as np
>>>
>>> evtarr = EventArray(np.arange(0, 30, 10)*s,
... labels=np.array(['trig0', 'trig1', 'trig2'],
... dtype='S'))
>>>
>>> evtarr.times
array([ 0., 10., 20.]) * s
>>> evtarr.labels
array(['trig0', 'trig1', 'trig2'],
dtype='|S5')
times: | (quantity array 1D) The time of the events. |
---|---|
labels: | (numpy.array 1D dtype=’S’) Names or labels for the events. |
name: | (str) A label for the dataset. |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
A period of time with a start point and duration.
Similar to Event but with a duration. Useful for describing a period, the state of a subject, etc.
Usage:
>>> from neo.core import Epoch
>>> from quantities import s, ms
>>>
>>> epc = Epoch(time=50*s, duration=200*ms, label='button pressed')
>>>
>>> epc.time
array(50.0) * s
>>> epc.duration
array(200.0) * ms
>>> epc.label
'button pressed'
time: | (quantity scalar) The start of the time period. |
---|---|
duration: | (quantity scalar) The length of the time period. |
label: | (str) A name or label for the time period. |
name: | (str) A label for the dataset. |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
Array of epochs. Introduced for performance reason.
An EpochArray is prefered to a list of Epoch objects.
Usage:
>>> from neo.core import EpochArray
>>> from quantities import s, ms
>>> import numpy as np
>>>
>>> epcarr = EpochArray(times=np.arange(0, 30, 10)*s,
... durations=[10, 5, 7]*ms,
... labels=np.array(['btn0', 'btn1', 'btn2'],
... dtype='S'))
>>>
>>> epcarr.times
array([ 0., 10., 20.]) * s
>>> epcarr.durations
array([ 10., 5., 7.]) * ms
>>> epcarr.labels
array(['btn0', 'btn1', 'btn2'],
dtype='|S4')
times: | (quantity array 1D) The starts of the time periods. |
---|---|
durations: | (quantity array 1D) The length of the time period. |
labels: | (numpy.array 1D dtype=’S’) Names or labels for the time periods. |
name: | (str) A label for the dataset, |
---|---|
description: | (str) Text description, |
file_origin: | (str) Filesystem path or URL of the original data file. |
A single spike.
Object to represent one spike emitted by a Unit and represented by its time occurence and optional waveform.
>>> from quantities import s
>>> spk = Spike(3*s)
>>> spk.time
array(3.0) * s
time: | (quantity) The time of the spike. |
---|
name: | (str) A label for the dataset. |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
waveforms: | (quantity array 2D (channel_index, time)) The waveform of the spike. |
sampling_rate: | (quantity scalar) Number of samples per unit time for the waveform. |
left_sweep: | (quantity scalar) Time from the beginning of the waveform to the trigger time of the spike. |
sampling_period: | |
---|---|
(quantity scalar) Interval between two samples. (1/sampling_rate) | |
duration: | (quantity scalar) Duration of waveform, read-only. (waveform.shape[1] * sampling_period) |
right_sweep: | (quantity scalar) Time from the trigger time of the spike to the end of the waveform, read-only. (left_sweep + duration) |
SpikeTrain is a Quantity array of spike times.
It is an ensemble of action potentials (spikes) emitted by the same unit in a period of time.
Usage:
>>> from neo.core import SpikeTrain
>>> from quantities import s
>>>
>>> train = SpikeTrain([3, 4, 5]*s, t_stop=10.0)
>>> train2 = train[1:3]
>>>
>>> train.t_start
array(0.0) * s
>>> train.t_stop
array(10.0) * s
>>> train
<SpikeTrain(array([ 3., 4., 5.]) * s, [0.0 s, 10.0 s])>
>>> train2
<SpikeTrain(array([ 4., 5.]) * s, [0.0 s, 10.0 s])>
times: | (quantity array 1D, numpy array 1D, or list) The times of each spike. |
---|---|
units: | (quantity units) Required if times is a list or ndarray, not if it is a Quantity. |
t_stop: | (quantity scalar, numpy scalar, or float) Time at which SpikeTrain ended. This will be converted to the same units as times. This argument is required because it specifies the period of time over which spikes could have occurred. Note that t_start is highly recommended for the same reason. |
Note: If times contains values outside of the range [t_start, t_stop], an Exception is raised.
name: | (str) A label for the dataset. |
---|---|
description: | (str) Text description. |
file_origin: | (str) Filesystem path or URL of the original data file. |
t_start: | (quantity scalar, numpy scalar, or float) Time at which SpikeTrain began. This will be converted to the same units as times. Default: 0.0 seconds. |
waveforms: | (quantity array 3D (spike, channel_index, time)) The waveforms of each spike. |
sampling_rate: | (quantity scalar) Number of samples per unit time for the waveforms. |
left_sweep: | (quantity array 1D) Time from the beginning of the waveform to the trigger time of the spike. |
sort: | (bool) If True, the spike train will be sorted by time. |
dtype: | (numpy dtype or str) Override the dtype of the signal array. |
---|---|
copy: | (bool) Whether to copy the times array. True by default. Must be True when you request a change of units or dtype. |
sampling_period: | |
---|---|
(quantity scalar) Interval between two samples. (1/sampling_rate) | |
duration: | (quantity scalar) Duration over which spikes can occur, read-only. (t_stop - t_start) |
spike_duration: | (quantity scalar) Duration of a waveform, read-only. (waveform.shape[2] * sampling_period) |
right_sweep: | (quantity scalar) Time from the trigger times of the spikes to the end of the waveforms, read-only. (left_sweep + spike_duration) |
times: | (SpikeTrain) Returns the SpikeTrain without modification or copying. |