Wiki

Clone wiki

spyndle / Home

Spyndle logo

The Spyndle Python package has been programmed in the course of my postdoctoral researches on the characterization of sleep spindles [1-5] under the supervision of the Dr. Tore Nielsen. I expect it to be a place where the software code produced can be distributed openly and hopefully reused in research. This package is in active development in the context of my postdoctoral studies so I welcome comments, questions, requests, and contributions. Code contributions/modifications can be uploaded with "pull requests". Questions can be addressed directly to me by e-mail.

Example of usage

Installing Spyndle can be done easily using

#!bash
   easy_install spyndle
or
#!bash
   pip install spyndle
As I publish papers using Spyndle, I intend to provide - as much as the privacy/ethical context allows it - the executable snippets of code used to generate these presented results and figures. These example of use can be found in the [examples}(https://bitbucket.org/christian_oreilly/spyndle/src/master/spyndle/examples) directory of the project.

For example, the example_RITA_paper.py script correspond the code published in [5] and is as follow:

#!python

from spyndle.io import EDFReader, DatabaseMng
from spyndle.detector import SpindleDectectorRMS
from spyndle.propagation import SPFEvaluator
from spyndle.EEG import getAdjacentsPairs_10_20, plotArrowsBidirect, \
    plotColorMap, getActiveElectrodes

from urllib import  urlretrieve,  ContentTooShortError
from scipy import unique                                               

fileName        = "RITA_example.BDF"
detectionStages = ["Sleep stage 2"]
eventName       = "SpindleRMS"

print "Loading the data file from Internet. This may take some time, " \
      "the file is about 372 MB."
url = "https://bitbucket.org/christian_oreilly/spyndle/"\
      "downloads/RITA_example.BDF"

try:
    urlretrieve(url, fileName)
except ContentTooShortError:
     print "The retreived file is shorter than expected. The download as "\
           "probably been interrupted"
     exit

print "Creating a  database for recording final and intermediate results..."
dbPath = "C:\\Python27\\Lib\\site-packages\\spyndle\\examples\\RITA.db"
dbMng = DatabaseMng("sqlite:///" + dbPath)

print "Reading the .bdf file..."
readerEDF    = EDFReader(fileName)

print "Detecting spindles..."
detector = SpindleDectectorRMS(readerEDF)
detector.setDetectionStages(detectionStages)
detector.detectSpindles()
detector.saveSpindle(readerEDF, eventName, dbSession=dbMng.session)

print "Plotting the results in result_example_a.png..."
filteringDict = {"psgNight":fileName, "eventName":eventName}
spindles = dbMng.dmm.getTransientEvents(filteringDict, pandasFormat=True)                       
spindles["electrode"] = getActiveElectrodes(spindles["channelName"])
medDat = spindles.groupby("electrode").median()
plotColorMap(unique(spindles["electrode"]), medDat.duration, "example_a.png")

evaluator = SPFEvaluator(fileName, eventName, dbSession = dbMng.session, verbose=True)

print "Computing synchrone comparisons..."
evaluator.computeXCST(EDFReader, offset=0.0)

print "Computing asynchrone comparisons..."
evaluator.computeXCST(EDFReader, offset=0.5)

print "Computing SPFs..."
evaluator.computeSPF()            

print "Computing propagation averages..." 
evaluator.computeAveragePropagation()

print "Plotting the results in result_example_b.png..."
propagations = evaluator.getAveragePropagation(applyC3=True, applyC4=True)
propagations["ref"] = getActiveElectrodes(propagations["sourceChannelName"])
propagations["test"] = getActiveElectrodes(propagations["sinkChannelName"])
adjPairs = getAdjacentsPairs_10_20(unique(propagations["ref"]))
medDat = propagations.groupby(["ref", "test"]).median()["delay_mean"]
plotArrowsBidirect(medDat, adjPairs, filename="example_b.png")

This code download an EEG recording from the internet, detect spindles in all EEG channels, compute the propagation and produce a topographic map of the spindle duration (a) and a arrow plot of the spindle propagation between adjacent EEG channels (b).

Future work

Future work include, but is not limited to :

  • Forcing automatic verification of foreign key integrity for the SQL data model.
  • Implementing a complete traceability of data processing (i.e. always being capable of finding for a computationnal results what operations have been performed on what raw data and being able to reproduce these operations).
  • Code optimization to reduce processing time.
  • Implementing automatic sleep annotation (sleep stages, K-complexes, slow waves, artefacts, etc.).
  • Testing, testing, testion....
  • Documentation, documentation, documentation... (maybe using a tool such as Sphynx)

Citation

If using the Spyndle toolbox in your own research work, please cite related papers when appropriate.

Spindle propagation assessment:

[1] O’Reilly, C., & Nielsen, T. (2013). Assessing the propagation of EEG transient activity, Proceedings of the 8th International Workshop on Systems, Signal Processing and their Applications, Algiers, Algeria, 12-15 May 2013.

[2] O'Reilly, C., & Nielsen, T. (2013). Assessing EEG sleep spindle propagation. Part 1: Theory and proposed methodology. J Neurosci Methods. doi: 10.1016/j.jneumeth.2013.08.013 (authors's post-print version)

[3] O'Reilly, C., & Nielsen, T. (2013). Assessing EEG sleep spindle propagation. Part 2: Experimental characterization. J Neurosci Methods. doi: 10.1016/j.jneumeth.2013.08.014 (authors's post-print version)

Spindle detectors:

[4] O'Reilly, C. & Nielsen, T. Sleep spindle detection: Automation and performance evaluation using fine temporal resolution, Submitted to the Expert Systems with Applications, August 2013.

The Spyndle toolbox:

[5] O'Reilly, C., & Nielsen, T. The Spyndle toolbox: an open source software package for the investigation of EEG transient events. Submitted to the Revue internationale des technologies avancées, August 2013.


Christian O'Reilly

Updated