Skip to content

Commit

Permalink
Merge pull request #40 from neuromusic/detectors
Browse files Browse the repository at this point in the history
implements edge detection
  • Loading branch information
neuromusic authored Nov 2, 2017
2 parents 8169494 + 99e3d7d commit b20ee5c
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 24 deletions.
18 changes: 12 additions & 6 deletions neuroglia/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .utils import create_interpolator, events_to_xr_dim
from .spike import Smoother, DEFAULT_TAU

class EventTraceTensorizer(BaseEstimator,TransformerMixin):
class PeriEventTraceSampler(BaseEstimator,TransformerMixin):
"""docstring for EventTensorizer."""
def __init__(self, traces, sample_times):
self.sample_times = sample_times
Expand Down Expand Up @@ -38,11 +38,12 @@ def extractor(ev):
return xr.concat(tensor,dim=concat_dim)


class EventSpikeTensorizer(BaseEstimator,TransformerMixin):
"""docstring for EventSpikeTensorizer."""
def __init__(self, spikes, sample_times, tracizer=None,tracizer_kwargs=None):
class PeriEventSpikeSampler(BaseEstimator,TransformerMixin):
"""docstring for PeriEventSpikeSampler."""
def __init__(self, spikes, sample_times, fillna=True, tracizer=None,tracizer_kwargs=None):
self.spikes = spikes
self.sample_times = sample_times
self.fillna = fillna
self.Tracizer = tracizer
self.tracizer_kwargs = tracizer_kwargs

Expand Down Expand Up @@ -71,7 +72,7 @@ def extractor(ev):
tracizer = self.Tracizer(t,**self.tracizer_kwargs)
traces = tracizer.fit_transform(local_spikes)

traces.index = self.sample_times
traces.index = self.sample_times[:len(traces)]

return xr.DataArray(traces,dims=['sample_times','neuron'])

Expand All @@ -80,4 +81,9 @@ def extractor(ev):
concat_dim = events_to_xr_dim(X)

# concatenate the DataArrays into a single DataArray
return xr.concat(tensor,dim=concat_dim)
tensor = xr.concat(tensor,dim=concat_dim)

if self.fillna:
tensor = tensor.fillna(0)

return tensor
4 changes: 2 additions & 2 deletions neuroglia/spike.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ def get_neuron(neuron_spikes):
assert len(unique_neurons)==1
return unique_neurons[0]

class Binarizer(BaseEstimator,TransformerMixin):
"""Binarize a population of spike events into an array of spike counts.
class Binner(BaseEstimator,TransformerMixin):
"""Bin a population of spike events into an array of spike counts.
"""
def __init__(self,sample_times):
Expand Down
6 changes: 3 additions & 3 deletions neuroglia/tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
from sklearn.base import BaseEstimator, TransformerMixin
import numpy as np

class ResponseExtractor(BaseEstimator,TransformerMixin):
class ResponseReducer(BaseEstimator,TransformerMixin):
"""docstring for Annotator."""
def __init__(self, method='mean', dim='sample_times'):
super(ResponseExtractor, self).__init__()
super(ResponseReducer, self).__init__()

if method == 'mean':
self.method = np.mean
Expand All @@ -19,4 +19,4 @@ def fit(self, X, y=None):
return self

def transform(self, X):
return X.mean(dim=self.dim)
return X.reduce(self.method,dim=self.dim)
88 changes: 88 additions & 0 deletions neuroglia/trace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import numpy as np
import pandas as pd
from sklearn.base import TransformerMixin, BaseEstimator
from sklearn.preprocessing import binarize

class Binarizer(BaseEstimator, TransformerMixin):
"""docstring for scikit learn Binarizer
"""

def __init__(self, threshold=0.0, copy=True):
self.threshold = threshold
self.copy = copy

def fit(self, X, y=None):
return self

def transform(self, X):
df = True
try:
index = X.index
columns = X.columns
except AttributeError:
df = False

X_ = binarize(X, threshold=self.threshold, copy=self.copy)

if df:
return pd.DataFrame(data=X_,index=index,columns=columns)
else:
return X_



def edge_detector(X,falling=False):

df = True
try:
index = X.index
columns = X.columns
except AttributeError:
df = False

X = np.apply_along_axis(
func1d=np.diff,
axis=0,
arr=X.copy(),
)
empty_row = np.zeros(shape=(1,X.shape[1]),dtype=X.dtype)
X = np.vstack((empty_row,X))

if falling:
X = X < 0
else:
X = X > 0

X = X.astype(int)

if df:
return pd.DataFrame(data=X,index=index,columns=columns)
else:
return X

class EdgeDetector(BaseEstimator,TransformerMixin):
"""docstring for EdgeDetector."""
def __init__(self, falling=False):
self.falling = falling

def fit(self,X,y=None):
return self

def transform(self,X):

return edge_detector(X,self.falling)

class WhenTrueFinder(BaseEstimator,TransformerMixin):
"""docstring for WhenTrueFinder."""
def __init__(self):
pass

def fit(self,X,y=None):
return self

def transform(self,X):
return (X[X > 0]
.stack()
.reset_index()[['level_0','level_1']]
.rename(columns={'level_0':'time','level_1':'neuron'})
)
14 changes: 7 additions & 7 deletions tests/test_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import numpy.testing as npt
import xarray.testing as xrt

from neuroglia.event import EventTraceTensorizer, EventSpikeTensorizer
from neuroglia.event import PeriEventTraceSampler, PeriEventSpikeSampler

from sklearn.base import clone

Expand Down Expand Up @@ -37,8 +37,8 @@
TS = np.arange(0,1,0.01)


def test_EventTraceTensorizer_dims():
tensorizer = EventTraceTensorizer(DFF,sample_times=TS)
def test_PeriEventTraceSampler_dims():
tensorizer = PeriEventTraceSampler(DFF,sample_times=TS)
tensor = tensorizer.fit_transform(EVENTS)

npt.assert_equal(tensor['neuron'].data,NEURON)
Expand All @@ -47,8 +47,8 @@ def test_EventTraceTensorizer_dims():

clone(tensorizer)

def test_EventSpikeTensorizer():
tensorizer = EventSpikeTensorizer(SPIKES,sample_times=TS)
def test_PeriEventSpikeSampler():
tensorizer = PeriEventSpikeSampler(SPIKES,sample_times=TS)
tensor = tensorizer.fit_transform(EVENTS)

npt.assert_equal(tensor['neuron'].data,SPIKES['neuron'].unique())
Expand All @@ -58,9 +58,9 @@ def test_EventSpikeTensorizer():
clone(tensorizer)


def test_EventSpikeTensorizer_no_response():
def test_PeriEventSpikeSampler_no_response():

spikes = pd.DataFrame({'neuron':[0,0,1],'time':[0.01,0.2,1.6]})

tensorizer = EventSpikeTensorizer(spikes,sample_times=TS)
tensorizer = PeriEventSpikeSampler(spikes,sample_times=TS)
tensor = tensorizer.fit_transform(EVENTS)
6 changes: 3 additions & 3 deletions tests/test_spike.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import numpy.testing as npt
import xarray.testing as xrt

from neuroglia.spike import Smoother, Binarizer
from neuroglia.spike import Smoother, Binner

from sklearn.base import clone

Expand All @@ -21,8 +21,8 @@ def test_Smoother():
npt.assert_array_equal(smoothed.index,TS)
clone(smoother)

def test_Binarizer():
binarizer = Binarizer(sample_times=TS)
def test_Binner():
binarizer = Binner(sample_times=TS)
binarized = binarizer.fit_transform(SPIKES)

npt.assert_array_equal(binarized.index,TS[:-1])
Expand Down
6 changes: 3 additions & 3 deletions tests/test_tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import numpy.testing as npt
import xarray.testing as xrt

from neuroglia.tensor import ResponseExtractor
from neuroglia.tensor import ResponseReducer

LBL = ['a','b','a','b']
NRN = ['roi_1','roi_2']
Expand All @@ -26,8 +26,8 @@
},
)

def test_ResponseExtractor_smoke():
extractor = ResponseExtractor()
def test_ResponseReducer_smoke():
extractor = ResponseReducer()
responses = extractor.fit_transform(TENSOR)

npt.assert_array_equal(responses['event'],LBL)
Expand Down
90 changes: 90 additions & 0 deletions tests/test_traces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import numpy as np
import numpy.testing as npt

import pandas as pd
import pandas.testing as pdt

from neuroglia.trace import EdgeDetector, WhenTrueFinder, Binarizer

X = np.array(
[[0, 0, 1],
[1, 1, 0],
[0, 1, 1]
])

XDF = pd.DataFrame(
data=X,
index=[0.1,0.2,0.3],
columns=['n1','n2','n3'],
)

RISING = np.array(
[[0, 0, 0],
[1, 1, 0],
[0, 0, 1],
]
)

DF = pd.DataFrame(
data=RISING,
index=[0.1,0.2,0.3],
columns=['n1','n2','n3'],
)

FALLING = np.array(
[[0, 0, 0],
[0, 0, 1],
[1, 0, 0],
]
)

def test_EdgeDetector():
detector = EdgeDetector()
output = detector.fit_transform(X)
npt.assert_array_equal(output,RISING)

detector = EdgeDetector(falling=True)
output = detector.fit_transform(X)
npt.assert_array_equal(output,FALLING)

detector = EdgeDetector()
output = detector.fit_transform(XDF)
npt.assert_array_equal(output.values,RISING)
print(output)
print(DF)
pdt.assert_frame_equal(output,DF)


WHENTRUE = pd.DataFrame(dict(
neuron=['n1','n2','n3'],
time=[0.2,0.2,0.3],
)).set_index('time')

def test_WhenTrueFinder():
finder = WhenTrueFinder()
output = finder.fit_transform(DF)
output = output.sort_values(['time','neuron']).set_index('time')
print(output)
print(DF)
pdt.assert_frame_equal(output,WHENTRUE)

X2 = np.array(
[[0, 0, 1],
[1, 2, 0],
[0, 1, 10]
])

X2DF = pd.DataFrame(
data=X,
index=[0.1,0.2,0.3],
columns=['n1','n2','n3'],
)

def test_Binarizer():
binarizer = Binarizer()
output = binarizer.fit_transform(X2)
npt.assert_array_equal(output,X)

binarizer = Binarizer()
output = binarizer.fit_transform(X2DF)
pdt.assert_frame_equal(output,XDF)

0 comments on commit b20ee5c

Please sign in to comment.