Skip to content

Commit

Permalink
split test file into separate files
Browse files Browse the repository at this point in the history
  • Loading branch information
DominiqueMakowski committed Nov 25, 2019
1 parent 0d5afb4 commit 32a1d01
Show file tree
Hide file tree
Showing 12 changed files with 216 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,4 @@ ENV/
.mypy_cache/
.Rhistory
test.py
try_stuff.py
2 changes: 1 addition & 1 deletion docs/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Functions

This part of the documentation details the complete ``NeuroKit2`` for python API.

.. automodule:: TruScanEEGpy.signal
.. automodule:: neurokit2.signal
:members:


1 change: 1 addition & 0 deletions neurokit2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
__version__ = '0.0.1'

from .signal import *
from .events import *
4 changes: 4 additions & 0 deletions neurokit2/events/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""Submodule for NeuroKit."""

from .events_find import events_find
from .plot_events_in_signal import plot_events_in_signal
119 changes: 119 additions & 0 deletions neurokit2/events/events_find.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
import itertools

from ..signal import signal_binarize










def _events_find(event_channel, threshold="auto", keep="above"):
"""Internal function
"""
binary = signal_binarize(np.array(event_channel), threshold=threshold)

if keep != 'above':
binary = np.abs(binary - 1) # Reverse if events are below

# Initialize data
events = {"Onset":[], "Duration":[]}

index = 0
for event, group in (itertools.groupby(binary)):
duration = len(list(group))
if event == 1:
events["Onset"].append(index)
events["Duration"].append(duration)
index += duration

# Convert to array
events["Onset"] = np.array(events["Onset"])
events["Duration"] = np.array(events["Duration"])
return(events)













# ==============================================================================
# ==============================================================================
# ==============================================================================
# ==============================================================================
# ==============================================================================
# ==============================================================================
# ==============================================================================
# ==============================================================================
def events_find(event_channel, threshold="auto", keep="above", start_at=0, end_at=None, duration_min=1, duration_max=None):
"""
Find and select events based on a continuous signal.
Parameters
----------
event_channel : array or list
The channel containing the events.
threshold : str or float
The threshold value by which to select the events. If "auto", takes the value between the max and the min.
keep : str
"above" or "below", define the events as above or under the treshold. For photosensors, a white screen corresponds usually to higher values. Therefore, if your events are signaled by a black colour, events values are the lower ones, and you should set the cut to "below".
start_at, end_at : int
Keep events which onset is after, or before a particular time point.
duration_min, duration_max : int
The minimum or maximum duration of an event to be considered as such (in time points). Useful when spurious events are created due to very high sampling rate.
Returns
----------
dict
Dict containing two arrays, 'onset' for events onsets and 'duration' for events durations.
Example
----------
>>> import numpy as np
>>> import pandas as pd
>>> import neurokit2 as nk
>>>
>>> signal = np.cos(np.linspace(start=0, stop=20, num=1000))
>>> nk.events_find(signal)
{'Onset': array([ 0, 236, 550, 864]), 'Duration': array([ 79, 157, 157, 136])}
>>> nk.plot_events_in_signal(signal, events)
"""
events = _events_find(event_channel, threshold="auto", keep="above")

# Warning when no events detected
if len(events["Onset"]) == 0:
print("NeuroKit warning: events_find(): No events found. Check your event_channel or adjust 'threhsold' or 'keep' arguments.")
return(events)

# Remove based on duration
to_keep = np.full(len(events["Onset"]), True)
to_keep[events["Duration"] < duration_min] = False
if duration_max is not None:
to_keep[events["Duration"] > duration_max] = False
events["Onset"] = events["Onset"][to_keep]
events["Duration"] = events["Duration"][to_keep]

# Remove based on index
events["Onset"] = events["Onset"][events["Onset"] >= start_at]
events["Duration"] = events["Duration"][events["Onset"] >= start_at]

if end_at is not None:
events["Onset"] = events["Onset"][events["Onset"] <= end_at]
events["Duration"] = events["Duration"][events["Onset"] <= end_at]


return(events)
57 changes: 57 additions & 0 deletions neurokit2/events/plot_events_in_signal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np

import matplotlib.pyplot as plt






def plot_events_in_signal(signal, events, show=True, color="red", linestyle="--"):
"""
Plot events in signal.
Parameters
----------
signal : array or DataFrame
Signal array (can be a dataframe with many signals).
events_onsets : list or ndarray
Events onset location. If a dict is passed (e.g., from 'events_find()'), will select only the 'Onset' list.
show : bool
If True, will return a plot. If False, will return a DataFrame that can be plotted externally.
color, linestyle : str
Other arguments to pass to matplotlib plotting.
Examples
----------
>>> import numpy as np
>>> import pandas as pd
>>> import neurokit2 as nk
>>>
>>> signal = np.cos(np.linspace(start=0, stop=20, num=1000))
>>> events = nk.events_find(signal)
>>> nk.plot_events_in_signal(signal, events)
"""

if isinstance(events, dict):
events = events["Onset"]

if isinstance(signal, pd.DataFrame) is False:
df = pd.DataFrame({"Signal": signal})


# Plot if necessary
if show:
df.plot()
for event in events:
plt.axvline(event, color=color, linestyle=linestyle)

else:
df["Event_Onset"] = 0
df.iloc[events] = 1
return(df)



3 changes: 1 addition & 2 deletions neurokit2/signal/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
"""Submodule for NeuroKit."""

from .signal_binarize import *

from .signal_binarize import signal_binarize
14 changes: 3 additions & 11 deletions neurokit2/signal/signal_binarize.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
import numpy as np




def signal_binarize(signal, threshold="auto", cut="higher"):
def signal_binarize(signal, threshold="auto"):
"""Binarize a continuous signal.
Parameters
Expand All @@ -14,8 +12,6 @@ def signal_binarize(signal, threshold="auto", cut="higher"):
The signal channel.
threshold : float
The threshold value by which to select the events. If "auto", takes the value between the max and the min.
cut : str
"higher" or "lower", define the events as above or under the threshold. For photosensors, a white screen corresponds usually to higher values. Therefore, if your events were signalled by a black colour, events values would be the lower ones, and you should set the cut to "lower".
Returns
-------
Expand Down Expand Up @@ -43,12 +39,8 @@ def signal_binarize(signal, threshold="auto", cut="higher"):
if threshold == "auto":
threshold = np.mean([np.max(signal), np.min(signal)])

if cut == "higher":
signal[signal > threshold] = 1
signal[signal <= threshold] = 0
else:
signal[signal > threshold] = 0
signal[signal <= threshold] = 1
signal[signal > threshold] = 1
signal[signal <= threshold] = 0

if return_list:
return(list(signal))
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ def find_version():


# Dependencies
requirements = ['pandas', 'numpy', ]
requirements = ['pandas', 'numpy', 'matplotlib', ]
setup_requirements = ['pytest-runner', ]
test_requirements = ['pytest', 'coverage', 'pandas', 'numpy', ]
test_requirements = requirements + ['pytest', 'coverage', ]


# Setup
Expand Down
13 changes: 0 additions & 13 deletions test.py

This file was deleted.

7 changes: 3 additions & 4 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,19 @@
doctest.testmod()
pytest.main()

def test_foo():
assert 3 == 3
from .tests_events import *

# =============================================================================
# Signal
# =============================================================================



def test_signal_binarize():

signal = np.cos(np.linspace(start=0, stop=20, num=1000))
binary = nk.signal_binarize(signal)
assert len(binary) == 1000

binary = nk.signal_binarize(list(signal))
assert len(binary) == 1000
24 changes: 24 additions & 0 deletions tests/tests_events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import numpy as np
import pandas as pd
import neurokit2 as nk

# =============================================================================
# Events
# =============================================================================



def test_events_find():

signal = np.cos(np.linspace(start=0, stop=20, num=1000))
events = nk.events_find(signal)
assert list(events["Onset"]) == [0, 236, 550, 864]



def test_plot_events_in_signal():

signal = np.cos(np.linspace(start=0, stop=20, num=1000))
events = nk.events_find(signal)
data = nk.plot_events_in_signal(signal, events, show=False)
assert len(data['Event_Onset']) == 1000

0 comments on commit 32a1d01

Please sign in to comment.