-
Notifications
You must be signed in to change notification settings - Fork 0
Mapping
This document describes how the Neo data model is mapped into NIX when writing using the Neo-NixIO.
Each Neo object maps to at least one instance of a NIX object. Each object's attributes are mapped into the corresponding attributes in NIX. If there is no NIX attribute that holds the same meaning as the Neo attribute, the object's metadata section is used.
Each NIX object refers to one metadata Section.
This section shares the NIX object's name.
The type is the same as the type attribute with the suffix .metadata.
Metadata Sections are created when the object is created, even if there are no properties to be stored.
The NIX metadata tree reflects the Neo object tree.
Since Version 1.4.3, NIXPY allows any string to be used as a unit. Previously, NIX restricted dimensions to SI units. With this change, the Neo-NixIO can store any unit specified in Neo into the file without much trouble. In some situations, however, there is a small change that needs to be made for the data in the NIX file to be consistent.
Certain attribute values are scaled to fit a particular unit when writing.
The clearest example of this is t_start for AnalogSignal.
When written to NIX, this attribute is stored in the time dimension, a dimension object of type SampledDimension.
The unit of this attribute must match the signal's time dimension unit (the offset, which is the t_start counterpart, does not have its own unit; instead it is stored in the time dimension and shares the same unit as the sampling frequency).
In the cases where it does not match, the attribute is rescaled to match, the original unit is stored as metadata, and it is restored to its original value when reading.
Example behaviour:
-
AnalogSignalwith:sampling_period = 0.1 * mst_start = 1 * s
- When writing to NIX this will be converted to a
DataArraywith aSampledDimensionto represent the time axis with:sampling_interval = 0.1offset = 1000unit = "ms"
- In order to losslessly recover the state of the original
AnalogSignal, the following property is stored in theDataArray's metadata:da.metadata["t_start"] = 1da.metadata["t_start"].unit = "s"
Objects in Neo do not require names to be unique or non-empty. This is an issue for NIX since NIX requires non-empty, unique names. To work around this, the following naming scheme is implemented during writing:
- When a Neo object is written to NIX, a unique
nix_nameis generated. - The NIX name is added to the Neo object as an annotation (
nix_name). - The Neo object's original name is stored in the NIX object's metadata (
neo_name). - When reading the file, the Neo object's original name is restored and the autogenerated NIX name is stored as an annotation.
During step 1., if the Neo object already has a nix_name annotation, that name is used instead of generating a new one.
See the Naming Example for an example of this behaviour.
When a Block is written to a file, the NixIO checks whether the neo.Block has a nix_name annotation.
If it does and it matches the name of a nix.Block already in the file, the entire Block is deleted and rewritten.
If no conflict exists, the Block is written alongside existing ones.
See the Naming Example for an example of this behaviour.
Maps to nix.Block.
-
Attributes
Neo NIX Block.name(string) Block.name(string) Block.description(string) Block.definition(string) Block.rec_datetime(datetime) Block.created_at(int) Block.file_datetime(datetime) Block.metadata(Section) [1] Block.file_origin(string) Block.metadata(Section) [1] -
Objects
- neo.Block.segments(Segment[]):
- Maps to nix.Block.groups(Group[]).
- See the neo.Segment section for details.
- neo.Block.channel_indexes(ChannelIndex[]):
- Maps to nix.Block.sources(Source[]) with
type = "neo.channelindex". - See the neo.ChannelIndex section for details.
- Maps to nix.Block.sources(Source[]) with
- neo.Block.segments(Segment[]):
Maps to nix.Group.
-
Attributes
Neo NIX Segment.name(string) Group.name(string) Segment.description(string) Group.definition(string) Segment.rec_datetime(datetime) Group.created_at(int) Segment.file_datetime(datetime) Group.metadata(Section) [1] Segment.file_origin(string) Group.metadata(Section) [1] -
Objects
- Segment.analogsignals(AnalogSignal[]) & Segment.irregularlysampledsignals(IrregularlySampledSignal[]):
For each item in both lists, a
nix.DataArrayis created which holds the signal data and attributes. Thetypeattribute of theDataArrayis set toneo.analogsignalorneo.irregularlysampledsignalaccordingly. These are stored in theGroup.data_arrayslist. See the neo.AnalogSignal and neo.IrregularlySampledSignal sections for details.- Signal objects in Neo can be grouped, e.g.,
Segment.analogsignalsis a list ofAnalogSignalobjects, each of which can hold multiple signals. In order to be able to reconstruct the original signal groupings, allDataArrayobjects that belong to the sameAnalogSignal(orIrregularlySampledSignal) have theirmetadataattribute point to the sameSection.
- Signal objects in Neo can be grouped, e.g.,
- Segment.epochs(Epoch[]):
For each item in
Segment.epochs, anix.MultiTagis created withtype = neo.epoch. This is stored in theGroup.multi_tagslist. See the neo.Epoch section for details. - Segment.events(Event[]):
For each item in
Segment.events, anix.MultiTagis created withtype = neo.event. This is stored in theGroup.multi_tagslist. See the neo.Event section for details. - Segment.spiketrains(SpikeTrain[]):
For each item in
Segment.spiketrains, anix.MultiTagis created withtype = neo.spiketrain. This is stored in theGroup.multi_tagslist. See the neo.SpikeTrain section for details.
- Segment.analogsignals(AnalogSignal[]) & Segment.irregularlysampledsignals(IrregularlySampledSignal[]):
For each item in both lists, a
Maps to nix.Source with type = neo.channelindex.
-
Attributes
Neo NIX ChannelIndex.name(string) Source.name(string) ChannelIndex.description(string) Source.definition(string) -
Objects
- For each channel in
ChannelIndex, determined by theindexarray, anix.Sourceis created withtype = neo.channelindex.- The name of each channel is the NIX name of the
ChannelIndexobject withChannelIndex<N>to it (where<N>is an incremental index). - Each channel has a metadata section which stores:
- A property that specifies its channel index, from
channel_indexes. - A property that stores the corresponding name, from
channel_names(if available). - A property that stores the corresponding id, from
channel_ids(if available). - A property that stores the corresponding
(x, y, z)coordinate, with unit, fromcoordinates(if available).
- A property that specifies its channel index, from
- The name of each channel is the NIX name of the
-
ChannelIndex.unitsMaps tonix.Sourcewithtype = neo.unit. See the neo.Unit section for details.
- For each channel in
-
AnalogSignal and IrregularlySampledSignal references
- The
nix.DataArrayobjects which represent theneo.AnalogSignalandneo.IrregularlySampedSignalobjects referenced by theneo.ChannelIndex, reference the respectivenix.Sourceobject (the reference direction is reversed).
- The
Maps to a nix.DataArray with type = neo.analogsignal.
-
Attributes
Neo NIX AnalogSignal.name(string) DataArray.name(string) AnalogSignal.description(string) DataArray.definition(string) -
Objects
- AnalogSignal.signal(Quantity 2D):
- Maps to a set of
DataArray.data(DataType[]), one for each signal in the signal group. -
DataArray.unit(string)is set based on the units of the Quantity array (AnalogSignal.signal). -
DataArray.dimensions(Dimension[])contains two objects:- A
SampledDimensionto denote that the signals are regularly sampled. The attributes of this dimension are:-
sampling_intervalassigned from the value ofAnalogSignal.sampling_rate(Quantity scalar). -
offsetassigned from the value ofAnalogSignal.t_start(Quantity scalar). -
unitinheriting the value of theDataArray.unit.
-
- A
SetDimensionto denote that the second dimension represents a set (collection) of signals.
- A
- Maps to a set of
- AnalogSignal.signal(Quantity 2D):
-
ChannelIndex references
- If a
neo.AnalogSignalis referenced by aneo.ChannelIndex, thenix.DataArrays each reference the correspondingnix.Source.
- If a
Maps to a nix.DataArray with type = neo.irregularlysampledsignal.
-
Attributes
Neo NIX IrregularlySampledSignal.name(string) DataArray.name(string) IrregularlySampledSignal.description(string) DataArray.definition(string) -
Objects
- IrregularlySampledSignal.signal(Quantity 2D):
- Maps to a set of
DataArray.data(DataType[]), one for each signal in the signal group. -
DataArray.unit(string)is set based on the units of the Quantity array (IrregularlySampledSignal.signal). -
DataArray.dimensions(Dimension[])contains two objects:- A
RangeDimensionto denote that the signals are irregularly sampled. The attributes of this dimension are:-
ticksassigned from the value ofIrregularlySampledSignal.times(Quantity 1D). -
unitinheriting the value of theDataArray.unit.
-
- A
SetDimensionto denote that the second dimension represents a set (collection) of signals.
- A
- Maps to a set of
- IrregularlySampledSignal.signal(Quantity 2D):
-
ChannelIndex references
- If a
neo.IrregularlySampedSignalis referenced by aneo.ChannelIndex, thenix.DataArrays each reference the correspondingnix.Source.
- If a
Maps to a nix.MultiTag with type = neo.epoch.
-
Attributes
Neo NIX Epoch.name(string) MultiTag.name(string) Epoch.description(string) MultiTag.definition(string) -
Objects
- Epoch.times(Quantity 1D) maps to
MultiTag.positions(DataArray)with typeneo.epoch.times. - Epoch.durations(Quantity 1D) maps to
MultiTag.extents(DataArray)with typeneo.epoch.durations. - Epoch.labels(string[]) maps to the
labelsattribute of aSetDimensionof the positionsDataArray. TheSetDimensionis also referenced by the extentsDataArray. - The
referencesattribute of thenix.MultiTagpoints to all theAnalogSignalandIrregularlySampledSignalobjects that exist in the sameneo.Segmentas the epoch.
- Epoch.times(Quantity 1D) maps to
Maps to a nix.MultiTag with type = neo.event.
-
Attributes
Neo NIX Event.name(string) MultiTag.name(string) Event.description(string) MultiTag.definition(string) -
Objects
- Event.times(Quantity 1D) maps to
MultiTag.positions(DataArray)with typeneo.event.times. - Event.labels(string[]) maps to the
labelsattribute of aSetDimensionof the positionsDataArray. - The
referencesattribute of thenix.MultiTagpoints to all theAnalogSignalandIrregularlySampledSignalobjects that exist in the sameneo.Segmentas the event.
- Event.times(Quantity 1D) maps to
Maps to a nix.MultiTag with type = neo.spiketrain.
-
Attributes
Neo NIX SpikeTrain.name(string) MultiTag.name(string) SpikeTrain.description(string) MultiTag.definition(string) SpikeTrain.t_start(Quantity scalar) MultiTag.metadata(Section) [1] SpikeTrain.t_stop(Quantity scalar) MultiTag.metadata(Section) [1] SpikeTrain.left_sweep(Quantity scalar) MultiTag.metadata(Section) [1] -
Objects
- SpikeTrain.times(Quantity 1D):
- Maps to
MultiTag.positions(DataArray). - The positions
DataArrayis of typeneo.spiketrainand has a singleSetDimension.
- Maps to
- SpikeTrain.waveforms(Quantity 3D):
- Waveform data and metadata associated with spikes are stored in a
DataArrayof typeneo.waveforms. - The
DataArrayis associated with the spiketrainMultiTagvia anix.Feature. Specifically,MultiTag.featuresholds a reference to a singleFeaturewithlink_type = indexed. -
Feature.datarefers to theDataArraywhere the waveforms are stored. - The
DataArrayalso refers to ametadataSection that stores theleft_sweepvalue. - The
DataArrayhas 3 dimensions:-
SetDimension. -
SetDimension. -
SampledDimension: TheSpikeTrain.sampling_rateis stored in this dimension'ssampling_intervaland theunitis set accordingly.
-
- Waveform data and metadata associated with spikes are stored in a
- SpikeTrain.times(Quantity 1D):
-
Unit references
- If a
neo.SpikeTrainis referenced by aneo.Unit, thenix.MultiTagreferences the correspondingnix.Sourceas well as the Unit's parentneo.ChannelIndex.
- If a
Maps to a nix.Source with type = neo.unit.
-
Attributes
Neo NIX Unit.name(string) Source.name(string) Unit.description(string) Source.definition(string) -
nix.Sourceobjects that representneo.Units are created on the correspondingnix.Sourcewhich represents the originalneo.RecordingChannelGroup. -
SpikeTrain references
- The
nix.MultiTagobjects which represent theneo.SpikeTrainobjects referenced by theneo.Unit, reference the respectivenix.Sourceobject (the reference direction is reversed).
- The