Skip to content

Commit

Permalink
Merge cec9415 into 32f5459
Browse files Browse the repository at this point in the history
  • Loading branch information
jpgill86 committed Feb 8, 2020
2 parents 32f5459 + cec9415 commit e2cfeea
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 80 deletions.
5 changes: 2 additions & 3 deletions docs/metadata.rst
Expand Up @@ -610,9 +610,8 @@ Rectified Area Under the Curve (RAUC)
-------------------------------------

One way to simplify a high-frequency signal is by plotted a time series of the
rectified area under the curve (RAUC). Note that RAUCs are calculated
automatically only in the standalone application and only if fast loading is
off (``lazy=False``).
rectified area under the curve (RAUC). Note that RAUCs are calculated only if
fast loading is off (``lazy=False``).

For each signal, the baseline (mean or median) is optionally subtracted off.
The signal is then rectified (absolute value) and divided into non-overlapping
Expand Down
24 changes: 21 additions & 3 deletions neurotic/datasets/data.py
Expand Up @@ -36,8 +36,10 @@ def load_dataset(metadata, lazy=False, signal_group_mode='split-all', filter_eve
``epoch_encoder_file`` and spike trains loaded from ``tridesclous_file``
are added to the Neo Block.
If ``lazy=False``, filters given in ``metadata`` are applied to the
signals and amplitude discriminators are run to detect spikes.
If ``lazy=False``, parameters given in ``metadata`` are used to apply
filters to the signals, to detect spikes using amplitude discriminators, to
detect bursts of spikes, and to calculate the rectified area under the
curve (RAUC) for each signal.
"""

# read in the electrophysiology data
Expand Down Expand Up @@ -83,6 +85,22 @@ def load_dataset(metadata, lazy=False, signal_group_mode='split-all', filter_eve
blk.segments[0].epochs.sort(key=lambda ep: ep.name)
blk.segments[0].events.sort(key=lambda ev: ev.name)

# compute rectified area under the curve (RAUC) for each signal if not
# using lazy loading of signals
if not lazy:
for sig in blk.segments[0].analogsignals:
rauc_sig = _elephant_tools.rauc(
signal=sig,
baseline=metadata['rauc_baseline'],
bin_duration=metadata['rauc_bin_duration']*pq.s,
)
rauc_sig.name = sig.name + ' RAUC'
sig.annotate(
rauc_sig=rauc_sig,
rauc_baseline=metadata['rauc_baseline'],
rauc_bin_duration=metadata['rauc_bin_duration']*pq.s,
)

return blk

def _get_io(metadata):
Expand Down Expand Up @@ -610,7 +628,7 @@ def _run_burst_detectors(metadata, blk):

spikeTrainNameToIndex = {st.name:i for i, st in enumerate(blk.segments[0].spiketrains)}

# detect bursts spikes using frequency thresholds
# detect bursts of spikes using frequency thresholds
for detector in metadata['burst_detectors']:

index = spikeTrainNameToIndex.get(detector['spiketrain'], None)
Expand Down
14 changes: 2 additions & 12 deletions neurotic/example/example-notebook.ipynb
Expand Up @@ -173,23 +173,13 @@
"# - this decreases loading time and consumes much less memory, especially\n",
"# for large files\n",
"# - to take advantage of these benefits, signal filtering, amplitude\n",
"# window spike discrimination, and rauc computation must be disabled\n",
"# window spike discrimination, and RAUC computation must be disabled\n",
"# - spike markers on signals are currently incompatible with lazy loading\n",
"lazy = False\n",
"\n",
"blk = neurotic.load_dataset(metadata, lazy=lazy)\n",
"\n",
"# compute rectified area under the curve (RAUC) for each signal\n",
"# - these computations require loading the entire file now, so only\n",
"# perform them if we're not using lazy loading\n",
"rauc_sigs = []\n",
"if not lazy:\n",
" for sig in blk.segments[0].analogsignals:\n",
" rauc = neurotic._elephant_tools.rauc(sig, baseline=metadata['rauc_baseline'], bin_duration=metadata['rauc_bin_duration']*pq.s)\n",
" rauc.name = sig.name + ' RAUC'\n",
" rauc_sigs.append(rauc)\n",
"\n",
"ephyviewer_config = neurotic.EphyviewerConfiguratorWidget(metadata, blk, rauc_sigs, lazy)\n",
"ephyviewer_config = neurotic.EphyviewerConfiguratorWidget(metadata, blk, lazy)\n",
"ephyviewer_config.show_all()\n",
"display(ephyviewer_config)"
]
Expand Down
107 changes: 55 additions & 52 deletions neurotic/gui/config.py
Expand Up @@ -56,14 +56,13 @@ class EphyviewerConfigurator():
and should be used if there is already a Qt app running.
"""

def __init__(self, metadata, blk, rauc_sigs = None, lazy = False):
def __init__(self, metadata, blk, lazy = False):
"""
Initialize a new EphyviewerConfigurator.
"""

self.metadata = metadata
self.blk = blk
self.rauc_sigs = rauc_sigs
self.lazy = lazy

self.viewer_settings = {
Expand Down Expand Up @@ -100,10 +99,10 @@ def __init__(self, metadata, blk, rauc_sigs = None, lazy = False):
}

# hide and disable viewers for which inputs are missing
if not self.rauc_sigs:
if not [sig.annotations['rauc_sig'] for sig in blk.segments[0].analogsignals if 'rauc_sig' in sig.annotations]:
self.viewer_settings['traces_rauc']['show'] = False
self.viewer_settings['traces_rauc']['disabled'] = True
self.viewer_settings['traces_rauc']['reason'] = 'Cannot enable because rauc_sigs is empty'
self.viewer_settings['traces_rauc']['reason'] = 'Cannot enable because there are no RAUC signals'
if not self.blk.segments[0].spiketrains:
self.viewer_settings['spike_trains']['show'] = False
self.viewer_settings['spike_trains']['disabled'] = True
Expand Down Expand Up @@ -424,54 +423,58 @@ def create_ephyviewer_window(self, theme='light', support_increased_line_width=F
########################################################################
# TRACES OF RAUC

if self.is_shown('traces_rauc') and self.rauc_sigs is not None:

sig_rauc_source = ephyviewer.InMemoryAnalogSignalSource(
signals = np.concatenate([self.rauc_sigs[p['index']].as_array() for p in self.metadata['plots']], axis = 1),
sample_rate = self.rauc_sigs[0].sampling_rate, # assuming all AnalogSignals have the same sampling rate
t_start = self.rauc_sigs[0].t_start, # assuming all AnalogSignals start at the same time
channel_names = [p['ylabel'] + ' RAUC' for p in self.metadata['plots']],
)
sources['signal_rauc'] = [sig_rauc_source]

trace_rauc_view = ephyviewer.TraceViewer(source = sources['signal_rauc'][0], name = 'signals rauc')

if 'signals' in win.viewers:
win.add_view(trace_rauc_view, tabify_with = 'signals')
else:
win.add_view(trace_rauc_view)

trace_rauc_view.params['line_width'] = line_width
trace_rauc_view.params['display_labels'] = True
trace_rauc_view.params['display_offset'] = True
trace_rauc_view.params['antialias'] = True

# set the theme
if theme != 'original':
trace_rauc_view.params['background_color'] = self.themes[theme]['background_color']
trace_rauc_view.params['vline_color'] = self.themes[theme]['vline_color']
trace_rauc_view.params['label_fill_color'] = self.themes[theme]['label_fill_color']
trace_rauc_view.params_controller.combo_cmap.setCurrentText(self.themes[theme]['cmap'])
trace_rauc_view.params_controller.on_automatic_color()

# set explicitly assigned signal colors
for name, color in sig_colors.items():
try:
index = [p['channel'] for p in self.metadata['plots']].index(name)
trace_rauc_view.by_channel_params['ch{}'.format(index), 'color'] = color
except ValueError:
# sig name may not have been found in the rauc trace list
pass

# adjust plot range
trace_rauc_view.params['ylim_max'] = 0.5
trace_rauc_view.params['ylim_min'] = -trace_rauc_view.source.nb_channel + 0.5
trace_rauc_view.params['scale_mode'] = 'by_channel'
for i, p in enumerate(self.metadata['plots']):
ylim_span = np.median(self.rauc_sigs[p['index']].magnitude) * 10
ylim_center = ylim_span / 2
trace_rauc_view.by_channel_params['ch{}'.format(i), 'gain'] = 1/ylim_span # rescale [ymin,ymax] across a unit
trace_rauc_view.by_channel_params['ch{}'.format(i), 'offset'] = -i - ylim_center/ylim_span # center [ymin,ymax] within the unit
if self.is_shown('traces_rauc'):

rauc_sigs = [sig.annotations['rauc_sig'] for sig in sigs if 'rauc_sig' in sig.annotations]

if rauc_sigs:

sig_rauc_source = ephyviewer.InMemoryAnalogSignalSource(
signals = np.concatenate([rauc_sigs[p['index']].as_array() for p in self.metadata['plots']], axis = 1),
sample_rate = rauc_sigs[0].sampling_rate, # assuming all AnalogSignals have the same sampling rate
t_start = rauc_sigs[0].t_start, # assuming all AnalogSignals start at the same time
channel_names = [p['ylabel'] + ' RAUC' for p in self.metadata['plots']],
)
sources['signal_rauc'] = [sig_rauc_source]

trace_rauc_view = ephyviewer.TraceViewer(source = sources['signal_rauc'][0], name = 'signals rauc')

if 'signals' in win.viewers:
win.add_view(trace_rauc_view, tabify_with = 'signals')
else:
win.add_view(trace_rauc_view)

trace_rauc_view.params['line_width'] = line_width
trace_rauc_view.params['display_labels'] = True
trace_rauc_view.params['display_offset'] = True
trace_rauc_view.params['antialias'] = True

# set the theme
if theme != 'original':
trace_rauc_view.params['background_color'] = self.themes[theme]['background_color']
trace_rauc_view.params['vline_color'] = self.themes[theme]['vline_color']
trace_rauc_view.params['label_fill_color'] = self.themes[theme]['label_fill_color']
trace_rauc_view.params_controller.combo_cmap.setCurrentText(self.themes[theme]['cmap'])
trace_rauc_view.params_controller.on_automatic_color()

# set explicitly assigned signal colors
for name, color in sig_colors.items():
try:
index = [p['channel'] for p in self.metadata['plots']].index(name)
trace_rauc_view.by_channel_params['ch{}'.format(index), 'color'] = color
except ValueError:
# sig name may not have been found in the rauc trace list
pass

# adjust plot range
trace_rauc_view.params['ylim_max'] = 0.5
trace_rauc_view.params['ylim_min'] = -trace_rauc_view.source.nb_channel + 0.5
trace_rauc_view.params['scale_mode'] = 'by_channel'
for i, p in enumerate(self.metadata['plots']):
ylim_span = np.median(rauc_sigs[p['index']].magnitude) * 10
ylim_center = ylim_span / 2
trace_rauc_view.by_channel_params['ch{}'.format(i), 'gain'] = 1/ylim_span # rescale [ymin,ymax] across a unit
trace_rauc_view.by_channel_params['ch{}'.format(i), 'offset'] = -i - ylim_center/ylim_span # center [ymin,ymax] within the unit

########################################################################
# FREQUENCY (EXPERIMENTAL AND COMPUTATIONALLY EXPENSIVE!)
Expand Down
3 changes: 1 addition & 2 deletions neurotic/gui/notebook.py
Expand Up @@ -153,7 +153,7 @@ class EphyviewerConfiguratorWidget(EphyviewerConfigurator):
ephyviewer.
"""

def __init__(self, metadata, blk, rauc_sigs = None, lazy = False):
def __init__(self, metadata, blk, lazy = False):
"""
Initialize a new EphyviewerConfiguratorWidget.
"""
Expand All @@ -165,7 +165,6 @@ def __init__(self, metadata, blk, rauc_sigs = None, lazy = False):
self,
metadata=metadata,
blk=blk,
rauc_sigs=rauc_sigs,
lazy=lazy)

self.viewer_settings['traces'].update({ 'icon': 'line-chart', 'description': 'Traces'})
Expand Down
9 changes: 1 addition & 8 deletions neurotic/gui/standalone.py
Expand Up @@ -281,14 +281,7 @@ def launch(self):

blk = load_dataset(metadata, lazy=self.lazy)

rauc_sigs = []
if not self.lazy:
for sig in blk.segments[0].analogsignals:
rauc = _elephant_tools.rauc(sig, baseline=metadata['rauc_baseline'], bin_duration=metadata['rauc_bin_duration']*pq.s)
rauc.name = sig.name + ' RAUC'
rauc_sigs.append(rauc)

ephyviewer_config = EphyviewerConfigurator(metadata, blk, rauc_sigs, self.lazy)
ephyviewer_config = EphyviewerConfigurator(metadata, blk, self.lazy)
ephyviewer_config.show_all()

win = ephyviewer_config.create_ephyviewer_window(theme=self.theme, support_increased_line_width=self.support_increased_line_width, show_datetime=self.show_datetime)
Expand Down

0 comments on commit e2cfeea

Please sign in to comment.