# Python Bindings for Neuroshare

The Neuroshare API is a standardized interface to access electrophysiology data stored in various different file formats. To do so, it uses format- specific shared libraries. Refer to the official website

> http://neuroshare.org

for more information.

The aim of this library is to provide a high level interface to the Neuroshare API, i.e. it focuses on API usability more then being a mere python version of the C API. Thus none of the original Neuroshare API calls are directly exposed but the interface consists of python objects that resemble (more or less) the Neuroshare Entities.

## Installation

The compile-time requirements for python-neuroshare are the ‘setuptools’ and the Python development files and a working C compiler (clang or gcc) and NumPy. For Debian based distributions, e.g. Ubuntu, this can easily be done with:

    $ sudo apt-get install clang python-setuptools \
                           python-dev python-numpy

After that, python-neuroshare is installed with the following command:

    $ sudo python setup.py install

Additional runtime dependencies:
  - The Neuroshare vendor DLLs for the specific data file(s)! Please refer to the following section for more information.

### Installation of vendor DLLs

Python-neuroshare relies on the vendor specific DLLs to access data files. Therefore the specific DLLs for each type of file must be downloaded and installed into one of the following locations:

    /usr/local/lib/neuroshare
    /usr/lib/neuroshare
    ~/.neuroshare

A (possibly incomplete) list of the vendor specific DLLs can be obtained be obtained from the neuroshare website:

> http://neuroshare.sourceforge.net/DLLLinks.shtml

Please note that you need the corresponding DLLs for your platform (e.g. Linux, 64-bit). If you find yourself in the situation that there is no DLL for your specific platform and you are either on a UNIX-like system you can use G-Node’s very one nswineproxy component to use the Windows 32 bit DLLs. Please refer to the nswineproxy homepage for more information:

> https://github.com/G-Node/nswineproxy

## Quickstart

Opening a file:

    import neuroshare as ns
    fd = ns.File ("NeuroshareExample.mcd")

Iterate over the entities in the file:

    for entity in fd.list_entities():
        print entity.label, entity.entity_type
        ... do something else with entity ...

Access analog signal data:

    analog1 = fd.entities[1] #open analog signal entity
    data, times, count = analog1.get_data() #load data

data will contain the raw data, times the timepoints of each datapoint and count how many datapoints in data are actually continous.

## Reporting Bugs & Submitting Patches

Any bugs can and should be filed to the project’s issue tracker at github:

> https://github.com/G-Node/python-neuroshare/issues

## Contact & Support

Support and discussion of python-neuroshare related questions happen in the official G-Node IRC channel #gnode on the freenode IRC network (cf. http://freenode.net).

# User’s Guide

## File structure and Entities

Neuroshare provides access to raw data and metadata (such as the sampling rate and creation date) via so called Entities, which groups data of the same type together. The standard defines 4 different entities: Events, Analog signals, Segments and Neural entities (i.e. spiketrains):

Event entities represent specific timepoints with associated data, e.g. trigger events.

Analog signal entities represents continuously sampled, i.e. digitized, analog data. Examples are waveforms recorded via an electrode (microelectrodes, EKG, EEG).

Segment entities contain cutouts of continuously sampled analog signals from one or more sources that are usually short in time. Most prominent example are waveforms of action potentials from one ore more electrodes.

Neural entities are arrays of timestamps when action potentials happened, i.e. arrays of spike times.

## Data access

All entities in the file are accessed by their entity index. Each individual entity can have one or more data entries attached to it; these are indetified by a sequential index.

## API

The basic desgin of the API closely follows the Neuroshare entity model. For all 4 entities there is a class that represents that entity:

- `EventEntity` for Events
- `AnalogEntity` for Analog signal entities
- `SegmentEntity` for Segements
- `NeuralEntity` for Neural entities

All entity classes derive from a common `Entity` class that provides metadata common to all entites such as the label (`Entity.label()`) and how many data entries are contained in the entity (`Entity.item_count()` or just `len(entity)`).

Opening a file is simply done by creating a `neuroshare.File` object with the path to the datafile as constructor argument: `fd = neuroshare.File('data.mcd')`. Individual enitities can be accessed via the `File.get_entity()` function or via indexing through the `File.entities()` property (e.g. `File.entities[idx]`).

Data is accessed via the `get_data()` function that all 4 entities provide. Consult the documentation of the individual functions for details.

## Code Examples

### List entities in a file

How to list all entities in a file called data.mcd:

    import neuroshare as ns
    fd = ns.File('data.mcd')
    for i, entity in enumerate(fd.entities):
        print('%04d: "%s" type: %d' % (i, entity.label, entity.entity_type))

This will produces the following output:

    0000: "trig0001 0000 0000 trig0001" type: 1
    0001: "elec0001 0000 0000       01" type: 2
    0002: "elec0001 0001 0001       02" type: 2
    0003: "elec0001 0002 0002       03" type: 2
    [...]

### Access the raw data inside an analog signal entity

To access the data and timestamps of an analog entity the `AnalogEntity.get_data()` is used:

    analog1 = fd.entities[1]  #access the entity 1

    #now load all the raw data
    data, timestamps, cont_count = analog1.get_data()

The `data` value is a `3-tuple` which contains the raw data and the timestamps for each datapoint. It is also possible to retrieve a subset of the available data:

    data = analog1.get_data(20, 10) #fetch 10 elements starting at index 20
    print("%d" % data[0].shape)
    # -> 10
    print (data[0])
    # ->
    # [  8.50000000e-05   7.00000000e-05   2.16666667e-05   3.16666667e-05
    #   3.66666667e-05   0.00000000e+00  -5.50000000e-05  -9.33333333e-05
    #  -6.66666667e-05   3.33333333e-06]

### Metadata

Metadata is exposed as python properties of the individual entities:

    print(analog1.units)
    # -> 'V'
    print(analog1.sample_rate)
    # -> 25000.0

# API Reference

## File

class `neuroshare.``File`(filename, library=None)

  Object that represents a datafile that can be open via neuroshare at the location given by `filename`. The file will be opened upon object construction.

  Individual entities can be opened via the `get_entity()` function or the `entities()` property. NB: The first entity index is 0

  `app_name`

    The name of the application that created the file

  `close`()

    Close the file.

  `comment`

    Additional comments

  `ctime`

    The time when this file was created, i.e. the data recorded. Returns a `datetime.datetime` object.

  `entities`

    Property that returns a proxy object to allow the opening of entities in a via indexing, ie:

        entity = datafile.entities[10] #retrieve the entity with at 10

  `entity_count`

    The number of entities in this file

  `file_type`

    Text description of the file type

  `get_entity`(entity_id)

    Open the entity at the given index.

  `list_entities`(start=0, end=-1)

    List all entities. The range can be limited via the `start` and `end` parameters.

  `time_span`

    Timespan of the data in the file [in seconds]

  `time_stamp_resolution`

    Minimum resolution of timestamps [in seconds]

## Entity

class `neuroshare.``Entity`(entity_id, nsfile, entity_info)

  Base class of all entities that are contained in a neuroshare file

  `entity_type`

    The type of the entity (of EntityType)

  `file`

    The underlying data file of this entity

  `get_index_by_time`(timepoint, position=0)

    Convert from a given timestamp to the corresponding index. The position argument controls how the timestamp is matched to the index. Options are:

    - before and inclusive of the timepoint (`EntityTime.Before`)
    - after and inclusive of the timepoint (`EntityTime.After`)
    - closest to timepoint (`EntityTime.Closest`) [default]
  `get_time_by_index`(index)

    Convert from a given index to the corresponding timestamp

  `id`

    The entity id of this entity

  `item_count`

    Number of data items for the specified entity in the file

  `label`

    The label or name of the entity

## Event Entity

class `neuroshare.``EventEntity`(nsfile, eid, info)

  Event entities represent specific timepoints with associated data, e.g. trigger events. Data can be binary (8, 16 or 32 bit) values, text or comma separated values (cvs).

  `csv_desc`

    Description of the csv fields

  `event_type`

    The type of the event:

    - binary (8, 16, 32 bit) [`EVENT_BYTE, EVENT_WORD, EVENT_DWORD`]
    - text [`EVENT_TEXT`]
    - comma separated values (csv) [`EVENT_CSV`]
  `get_data`(index)

    Retrieve the data at `index`. Returns a 2-tuple with the timestamp of the data at the first position (`[0]`) and the actual data a the second position (`[1]`)). Example use: `timestamp, data = event.get_data(0)`

  `max_data_length`

    Maximum length of the data for the event [in bytes]

  `min_data_length`

    Minimum length of the data for the event [in bytes]

## Analog Entity

class `neuroshare.``AnalogEntity`(nsfile, eid, info)

  `Entity` that represents continuously sampled, i.e. digitized, analog data. Examples are waveforms recorded via an electrode (microelectrodes, EKG, EEG). Actual data can be accessed via the `get_data()` function. .. note:: data may contain gaps (e.g. when no data is recorded between trails)

  `get_data`(index=0, count=-1)

    Retrieve raw data from file starting at `index` up to `count` elements. If no parameters are given retrieves all available data.

    Returns a tuple with three elements containing the raw data `[0]`, the timestamp of each data point `[1]` and how many of the data values are continuous `[2]`. Example use: `data, times, count = analog1.get_data()`

    Raw data and timestamp data are return as `numpy.ndarray`.

  `high_filter_type`

    Type of the filter used [text]

  `high_freq_corner`

    High frequency cutoff [in Hz] of the filter

  `high_freq_order`

    Order of the high frequency filter

  `location_user`

    Hardware specific additional location information

  `location_x`

    x coordinate of the source [in meters]

  `location_y`

    y coordinate of the source [in meters]

  `location_z`

    z coordinate of the source [in meters]

  `low_filter_type`

    Type of the filter used [text]

  `low_freq_corner`

    Low frequency cutoff [in Hz] of the filter

  `low_freq_order`

    Order of the high frequency filter

  `max_value`

    Maximum value of the data

  `min_value`

    Minimum value of the data

  `probe_info`

    Additional information

  `resolution`

    Minimal resolvable step size

  `sample_rate`

    Sampling rate (in Hz).

  `units`

    Physical units of measured data

## Neural Entity

class `neuroshare.``NeuralEntity`(nsfile, eid, info)

  Entity the represents timestamps of action potentials, i.e. spike times. Cutouts of the waveforms corresponding to spike data in a neural entity might be found in a separate `SegmentEntity` (cf. `source_entity_id()`).

  `get_data`(index=0, count=-1)

    Retrieve the spike times associated with this entity. A subset of the data can be requested via the `index` and `count` parameters.

  `probe_info`

    Additional information about the signal source

  `source_entity_id`

    [Optional] Id of the source entity of this spike, if any. For example the spike waveform of the action potential corresponding to this spike might have been recorded in a segment entity.

  `source_unit_id`

    [Optional] unit id used in the source entity (cf. `source_entity_id()`)

## Segment Entity

class `neuroshare.``SegmentEntity`(nsfile, eid, info)

  Segment entities contain cutouts of continuously sampled analog signals from one or more sources that are usually short in time. Most prominent example are waveforms of action potentials from one ore more electrodes.

  `get_data`(index)

    Retrieve the data at `index`

  `max_sample_count`

    Maximum number of samples in each data item

  `source_count`

    Number of sources for this segment entity.

  `sources`

    Property that provides access to the metadata of the individual sources of this entity.

    Returns a sequence of objects of type `SegmentSource`. Metadata properties of a SegmentSource are analogous to the `AnalogEntity`.

# Indices and tables

- Index
- Module Index
- Search Page

(c) 2013 Christian Kellner and the German Neuroinformatics Node