Skip to content

Commit

Permalink
merged back onto dev
Browse files Browse the repository at this point in the history
  • Loading branch information
parkin committed Mar 30, 2014
2 parents d6ce21e + cdeada8 commit 6dd198b
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 52 deletions.
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@ src/pypore/test/testDataFiles/*Events*

# Cython generated files
src/pypore/*.html
*.lprof
*.so
*.c
src/pypore/__pycache__/*
src/pypore/.pyxbld/*

# intellij stuff
.idea/
7 changes: 3 additions & 4 deletions src/pypore/file_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ def convert_file(filename, output_filename=None):

if output_filename is None:
output_filename = filename.split('.')[0] + '.h5'

save_file = data_file.open_file(output_filename, mode='w', sample_rate=sample_rate, nPoints=n_points)


save_file = data_file.open_file(output_filename, mode='w', sample_rate=sample_rate, n_points=n_points)
blocks_to_get = 1
data = reader.get_next_blocks(blocks_to_get)[0]

Expand Down Expand Up @@ -83,7 +82,7 @@ def filter_file(filename, filter_frequency, out_sample_rate, output_filename=Non
n_out = int(np.ceil(n_points * out_sample_rate / sample_rate))
filtered = sig.resample(filtered, num=n_out)

save_file = data_file.open_file(output_filename, mode='w', sample_rate=sample_rate, nPoints=filtered.size)
save_file = data_file.open_file(output_filename, mode='w', sample_rate=sample_rate, n_points=filtered.size)
save_file.root.data[:] = filtered[:]

save_file.flush()
Expand Down
6 changes: 3 additions & 3 deletions src/pypore/filetypes/data_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ def initialize_database(self, **kargs):
"""
Initializes the data_file.
:param kargs: Can pass in 'nPoints': Maximum number of data points for an event to be added.
:param kargs: Can pass in 'n_points': Maximum number of data points for an event to be added.
"""

filters = tb.Filters(complib='blosc', complevel=4)
shape = (kargs['nPoints'],)
shape = (kargs['n_points'],)
a = tb.FloatAtom()
if not 'data' in self.root:
self.createCArray(self.root, 'data', a, shape=shape, title='Data', filters=filters)
Expand All @@ -94,7 +94,7 @@ def open_file(*args, **kargs):
:param args: Arguments that get passed to :py:func:`tables.openFile`.
:param kargs: Arguments that get passed to :py:func:`tables.openFile`. Should additionally include:
- nPoints: Number of points that should be in the array.
- n_points: Number of points that should be in the array.
- sample_rate: Sample rate of the data.
:returns: :py:class:`pypore.filetypes.data_file.DataFile` -- an already opened
Expand Down
6 changes: 6 additions & 0 deletions src/pypore/filetypes/event_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,12 @@ def initialize_database(self, **kargs):
title="Raw data",
filters=filters)

def is_debug(self):
"""
:returns: True if the event was created with the debug keyword.
"""
return 'debug' in self.root

def remove_event(self, i):
"""
Deletes event i from /events/eventTable. Does nothing if
Expand Down
3 changes: 3 additions & 0 deletions src/pypore/filetypes/tests/test_event_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ def test_initialize_events_database_with_debug(self):

self._test_empty_events_group(events_group=database.root.events)

# Make sure is debug
self.assertTrue(database.is_debug())

# Make sure the debug group is there.
names = [x._v_name for x in database.walkGroups()]
self.assertIn('debug', names, 'No debug group.')
Expand Down
7 changes: 3 additions & 4 deletions src/pyporegui/my_threads.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,10 @@ class AnalyzeDataThread(QtCore.QThread):

readyForEvents = True

def __init__(self, file_names, parameters):
# def __init__(self, axes, filename='', threshold_strategy='adaptive', baseline_filter_parameter=0.93,
# threshold_direction='negative', min_event_length=10., max_event_length=1000.):
def __init__(self, file_names, parameters, debug):
QtCore.QThread.__init__(self)
self.parameters = parameters
self.debug = debug

self.file_names = file_names

Expand Down Expand Up @@ -113,7 +112,7 @@ def run(self):
self.time1 = time.time()
self._pipe, child_conn = Pipe()
self.p = Process(target=find_events, args=(self.file_names,),
kwargs={'parameters': self.parameters, 'pipe': child_conn})
kwargs={'parameters': self.parameters, 'pipe': child_conn, 'debug': self.debug})
self.p.start()
# child_conn needs to be closed in all processes before EOFError is thrown (on Linux)
# So close it here immediately
Expand Down
15 changes: 12 additions & 3 deletions src/pyporegui/widgets/event_finding_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ def _on_analyze(self):
self._dispatch_status_update(parameters['error'])
return

debug = self.debug_check_box.isChecked()

# Clear the current events
del self.events[:]
# self.prev_concat_time = 0.
Expand All @@ -218,7 +220,7 @@ def _on_analyze(self):
self._dispatch_status_update("Event Count: 0 Percent Done: 0")

# Start analyzing data in new analyzethread.
self.analyzethread = AnalyzeDataThread(file_names, parameters)
self.analyzethread = AnalyzeDataThread(file_names, parameters, debug)
self.analyzethread.dataReady.connect(self._analyze_data_thread_callback)
self.add_thread(self.analyzethread)
self.analyzethread.start()
Expand Down Expand Up @@ -301,6 +303,12 @@ def _create_left_widget(self, parent=None):
self.connect(self.stop_analyze_button, QtCore.SIGNAL('clicked()'), self._on_analyze_stop)
self.stop_analyze_button.setEnabled(False)

self.debug_check_box = QtGui.QCheckBox()
self.debug_check_box.setChecked(False)
self.debug_check_box.setText('Debug')
self.debug_check_box.setToolTip("When checked, extra data will be saved to the EventDatabase. This"
" data includes the data, baseline, and thresholds at each datapoint.")

# Analysis options
self.min_event_length_edit = QtGui.QLineEdit()
self.min_event_length_edit.setText('10.0')
Expand All @@ -323,11 +331,11 @@ def _create_left_widget(self, parent=None):
self.baseline_filter_parameter_edit = QtGui.QLineEdit()
self.baseline_filter_parameter_edit.setValidator(QtGui.QDoubleValidator(0, 10, 5, self.baseline_filter_parameter_edit))
self.baseline_filter_parameter_edit.setText('0.93')
adaptive_options_layout.addRow('Baseline Filter Parameter \'a_baseline\':', self.baseline_filter_parameter_edit)
adaptive_options_layout.addRow('Baseline Filter Parameter:', self.baseline_filter_parameter_edit)
self.variance_filter_parameter_edit = QtGui.QLineEdit()
self.variance_filter_parameter_edit.setValidator(QtGui.QDoubleValidator(0, 10, 5, self.variance_filter_parameter_edit))
self.variance_filter_parameter_edit.setText('0.99')
adaptive_options_layout.addRow('Variance Filter Parameter \'a_baseline\':', self.variance_filter_parameter_edit)
adaptive_options_layout.addRow('Variance Filter Parameter:', self.variance_filter_parameter_edit)
# need to cast to widget to add to QStackedLayout
adaptive_options_widget = QtGui.QWidget()
adaptive_options_widget.setLayout(adaptive_options_layout)
Expand Down Expand Up @@ -424,6 +432,7 @@ def _create_left_widget(self, parent=None):
vbox_left.addLayout(baseline_options)
vbox_left.addLayout(threshold_form)
vbox_left.addLayout(threshold_options)
vbox_left.addWidget(self.debug_check_box)
vbox_left.addLayout(hbox)

vbox_left_widget = QtGui.QWidget()
Expand Down
114 changes: 79 additions & 35 deletions src/pyporegui/widgets/event_viewing_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from pyporegui._thread_manager import _ThreadManager
from pyporegui.graphicsItems.my_plot_item import MyPlotItem
from pyporegui.file_items import FileListItem
from pyporegui.graphicsItems.path_item import PathItem

__all__ = ['EventViewingTab']

Expand Down Expand Up @@ -86,6 +87,9 @@ def _on_eventview_file_item_doubleclick(self, item):

event_count = h5file.get_event_count()

if h5file.is_debug():
self.plot_debug(h5file)

h5file.close()

self.event_display_edit.setMaxLength(int(event_count / 10) + 1)
Expand All @@ -94,27 +98,68 @@ def _on_eventview_file_item_doubleclick(self, item):
self.event_display_edit.setText('')
self.event_display_edit.setText('1')

def plotSingleEvents(self, event):
'''
def plot_debug(self, event_database):
"""
Plots the data, baseline, and thresholds of the debug group in the event_database, if they exist,
in the main plot.
:param event_database: An already open\
:class:`EventDatabase <pypore.filetypes.event_database.EventDatabase>`.
"""
if not event_database.is_debug():
return

self.eventview_plotwid.clear()

sample_rate = event_database.get_sample_rate()

# TODO remove the step_size.
step_size = 1000

data = event_database.root.debug.data[0][::step_size]

data_size = data.size
times = np.linspace(0, data_size *1.0/sample_rate, data_size)
item = PathItem(times, data)
item.setPen(pg.mkPen('w'))
self.eventview_plotwid.addItem(item)

baseline = event_database.root.debug.baseline[0][::step_size]
item = PathItem(times, baseline)
item.setPen(pg.mkPen('y'))
self.eventview_plotwid.addItem(item)

threshold_p = event_database.root.debug.threshold_positive[0][::step_size]
item = PathItem(times, threshold_p)
item.setPen(pg.mkPen('g'))
self.eventview_plotwid.addItem(item)

threshold_n = event_database.root.debug.threshold_negative[0][::step_size]
item = PathItem(times, threshold_n)
item.setPen(pg.mkPen('g'))
self.eventview_plotwid.addItem(item)

def plot_single_events(self, event):
"""
Plots the event on the plot with
'''
"""
h5file = eD.open_file(self.event_view_item.get_file_name(), mode='r')

eventCount = h5file.get_event_count()
event_count = h5file.get_event_count()

for i in xrange(3):
for j in xrange(3):
pos = 3 * i + j
if pos + event >= eventCount or pos + event < 0:
if pos + event >= event_count or pos + event < 0:
self.eventviewer_plots[pos].clear()
self.eventviewer_plots[pos].setTitle('')
else:
self.plotSingleEvent(h5file, event + pos, self.eventviewer_plots[pos])
self.plot_single_event(h5file, event + pos, self.eventviewer_plots[pos])
self.eventviewer_plots[pos].setTitle('Event ' + str(event + pos + 1))

h5file.close()

def plotSingleEvent(self, h5file, position, plot):
def plot_single_event(self, h5file, position, plot):
sample_rate = h5file.get_sample_rate()
row = h5file.get_event_row(position)
array_row = row['array_row']
Expand All @@ -130,7 +175,7 @@ def plotSingleEvent(self, h5file, position, plot):
plot.clear()
plot.plot(times, raw_data)
# plot the event points in yellow
plot.plot(times[raw_points_per_side:raw_points_per_side + event_length], \
plot.plot(times[raw_points_per_side:raw_points_per_side + event_length],
raw_data[raw_points_per_side:raw_points_per_side + event_length], pen='y')

# Plot the cusum levels
Expand All @@ -140,59 +185,59 @@ def plotSingleEvent(self, h5file, position, plot):
levels = h5file.get_levels_at(array_row)
indices = h5file.get_level_lengths_at(array_row)

levelTimes = np.zeros(2 * n_levels + 4)
levelValues = np.zeros(2 * n_levels + 4)
level_times = np.zeros(2 * n_levels + 4)
level_values = np.zeros(2 * n_levels + 4)

levelTimes[1] = 1.0 * (raw_points_per_side - 1) / sample_rate
levelValues[0] = levelValues[1] = baseline
level_times[1] = 1.0 * (raw_points_per_side - 1) / sample_rate
level_values[0] = level_values[1] = baseline
i = 0
length = 0
for i in xrange(n_levels):
levelTimes[2 * i + 2] = times[raw_points_per_side] + 1.0 * (length) / sample_rate
levelValues[2 * i + 2] = levels[i]
levelTimes[2 * i + 3] = times[raw_points_per_side] + 1.0 * (length + indices[i]) / sample_rate
levelValues[2 * i + 3] = levels[i]
level_times[2 * i + 2] = times[raw_points_per_side] + 1.0 * length / sample_rate
level_values[2 * i + 2] = levels[i]
level_times[2 * i + 3] = times[raw_points_per_side] + 1.0 * (length + indices[i]) / sample_rate
level_values[2 * i + 3] = levels[i]
length += indices[i]
i += 1
levelTimes[2 * i + 2] = times[raw_points_per_side + event_length]
levelTimes[2 * i + 3] = times[n - 1]
levelValues[2 * i + 2] = levelValues[2 * i + 3] = baseline
level_times[2 * i + 2] = times[raw_points_per_side + event_length]
level_times[2 * i + 3] = times[n - 1]
level_values[2 * i + 2] = level_values[2 * i + 3] = baseline

plot.plot(levelTimes, levelValues, pen='g')
plot.plot(level_times, level_values, pen='g')

def previous_clicked(self):
self.moveEventDisplayBy(-1 * len(self.eventviewer_plots))
self.move_event_display_by(-1 * len(self.eventviewer_plots))

def next_clicked(self):
self.moveEventDisplayBy(len(self.eventviewer_plots))
self.move_event_display_by(len(self.eventviewer_plots))

def moveEventDisplayBy(self, count):
'''
def move_event_display_by(self, count):
"""
Changes the event displayed on the event display plot to
current value + count
'''
h5eventCount = 0
"""
h5_event_count = 0
try:
h5file = eD.open_file(self.event_view_item.get_file_name())
h5eventCount = h5file.get_event_count()
h5_event_count = h5file.get_event_count()
h5file.close()
except:
return
try:
eventCount = int(self.event_display_edit.text())
if 0 < eventCount + count <= h5eventCount:
self.event_display_edit.setText(str(eventCount + count))
event_count = int(self.event_display_edit.text())
if 0 < event_count + count <= h5_event_count:
self.event_display_edit.setText(str(event_count + count))
except ValueError:
# if we can't parse the event display text but there are events,
# just set to zero
if h5eventCount > 0:
if h5_event_count > 0:
self.event_display_edit.setText('1')

def _eventDisplayEditOnChange(self, text):
def _event_display_edit_on_change(self, text):
if len(text) < 1:
return
position = int(self.event_display_edit.text())
self.plotSingleEvents(position - 1)
self.plot_single_events(position - 1)
return

def _create_event_viewer_plot_widget(self):
Expand All @@ -203,7 +248,6 @@ def _create_event_viewer_plot_widget(self):
self.eventview_plotwid = MyPlotItem(title='Current Trace', name='Plot')
wig.addItem(self.eventview_plotwid)
self.eventview_plotwid.enableAutoRange('xy', False)
self.eventview_p1 = self.eventview_plotwid.plot() # create an empty plot curve to be filled later

wig.nextRow()
# Create Qwt plot for concatenated events
Expand Down Expand Up @@ -235,7 +279,7 @@ def _create_event_viewer_plot_widget(self):
self.event_display_edit.setText('0')
self.event_display_edit.setMaxLength(1)
self.event_display_edit.setValidator(QtGui.QIntValidator(0, 0, self.event_display_edit))
self.event_display_edit.textChanged.connect(self._eventDisplayEditOnChange)
self.event_display_edit.textChanged.connect(self._event_display_edit_on_change)
event_select_toolbar.addWidget(self.event_display_edit)

self.event_count_text = QtGui.QLabel()
Expand Down

0 comments on commit 6dd198b

Please sign in to comment.