""" README =============================================================================== This is an adapter to represent stfio objects as neo objects. stfio is a standalone file i/o Python module that ships with the Stimfit program (http://www.stimfit.org). It's a Python wrapper around Stimfit's file i/o library (libstfio) that natively provides support for the following file types: - ABF (Axon binary file format; pClamp 6--9) - ABF2 (Axon binary file format 2; pClamp 10+) - ATF (Axon text file format) - AXGX/AXGD (Axograph X file format) - CFS (Cambridge electronic devices filing system) - HEKA (HEKA binary file format) - HDF5 (Hierarchical data format 5; only hdf5 files written by Stimfit or stfio are supported) In addition, libstfio can use the biosig file i/o library as an additional file handling backend (http://biosig.sourceforge.net/), extending support to more than 30 additional file formats (http://pub.ist.ac.at/~schloegl/biosig/TESTED). Based on exampleio.py and axonio.py from neo.io 08 Feb 2014, C. Schmidt-Hieber, University College London """ # needed for python 3 compatibility from __future__ import absolute_import import sys import numpy as np import quantities as pq from neo.io.baseio import BaseIO from neo.core import Block, Segment, AnalogSignal try: import stfio except ImportError as err: HAS_STFIO = False STFIO_ERR = err else: HAS_STFIO = True STFIO_ERR = None class StimfitIO(BaseIO): """ Class for converting a stfio Recording to a Neo object. Provides a standardized representation of the data as defined by the neo project; this is useful to explore the data with an increasing number of electrophysiology software tools that rely on the Neo standard. stfio is a standalone file i/o Python module that ships with the Stimfit program (http://www.stimfit.org). It is a Python wrapper around Stimfit's file i/o library (libstfio) that natively provides support for the following file types: - ABF (Axon binary file format; pClamp 6--9) - ABF2 (Axon binary file format 2; pClamp 10+) - ATF (Axon text file format) - AXGX/AXGD (Axograph X file format) - CFS (Cambridge electronic devices filing system) - HEKA (HEKA binary file format) - HDF5 (Hierarchical data format 5; only hdf5 files written by Stimfit or stfio are supported) In addition, libstfio can use the biosig file i/o library as an additional file handling backend (http://biosig.sourceforge.net/), extending support to more than 30 additional file formats (http://pub.ist.ac.at/~schloegl/biosig/TESTED). Example usage: >>> import neo >>> neo_obj = neo.io.StimfitIO("file.abf") or >>> import stfio >>> stfio_obj = stfio.read("file.abf") >>> neo_obj = neo.io.StimfitIO(stfio_obj) """ is_readable = True is_writable = False supported_objects = [Block, Segment, AnalogSignal] readable_objects = [Block] writeable_objects = [] has_header = False is_streameable = False read_params = {Block: []} write_params = None name = 'Stimfit' extensions = ['abf', 'dat', 'axgx', 'axgd', 'cfs'] mode = 'file' def __init__(self, filename=None): """ Arguments: filename : Either a filename or a stfio Recording object """ if not HAS_STFIO: raise STFIO_ERR BaseIO.__init__(self) if hasattr(filename, 'lower'): self.filename = filename self.stfio_rec = None else: self.stfio_rec = filename self.filename = None def read_block(self, lazy=False, cascade=True): if self.filename is not None: self.stfio_rec = stfio.read(self.filename) bl = Block() bl.description = self.stfio_rec.file_description bl.annotate(comment=self.stfio_rec.comment) try: bl.rec_datetime = self.stfio_rec.datetime except: bl.rec_datetime = None if not cascade: return bl dt = np.round(self.stfio_rec.dt * 1e-3, 9) * pq.s # ms to s sampling_rate = 1.0/dt t_start = 0 * pq.s # iterate over sections first: for j, recseg in enumerate(self.stfio_rec[0]): seg = Segment(index=j) length = len(recseg) # iterate over channels: for i, recsig in enumerate(self.stfio_rec): name = recsig.name unit = recsig.yunits try: pq.Quantity(1, unit) except: unit = '' if lazy: signal = pq.Quantity([], unit) else: signal = pq.Quantity(recsig[j], unit) anaSig = AnalogSignal(signal, sampling_rate=sampling_rate, t_start=t_start, name=str(name), channel_index=i) if lazy: anaSig.lazy_shape = length seg.analogsignals.append(anaSig) bl.segments.append(seg) t_start = t_start + length * dt bl.create_many_to_one_relationship() return bl