Commit f448c91d authored by Ronny Eichler's avatar Ronny Eichler
Browse files

Light vis integration as sub command

parent e5b73fb2
......@@ -25,16 +25,25 @@ if __name__ == "__main__":
# sub-parsers
subparsers = parser.add_subparsers(help='sub commands', dest='command')
# CLI
parser_cli = subparsers.add_parser('cli', help='Interactive CLI session')
# STATS
parser_stats = subparsers.add_parser('stats', help='Dataset statistics.')
parser_stats.add_argument('path', help='Relative or absolute path to directory',
default='.', nargs='?')
parser.ls = subparsers.add_parser('ls', help='Directory listing with basic stats (e.g. size)')
parser.ls .add_argument('path', help='Relative or absolute path to directory',
# LS
parser_ls = subparsers.add_parser('ls', help='Directory listing with basic stats (e.g. size)')
parser_ls .add_argument('path', help='Relative or absolute path to directory',
default='.', nargs='?')
# VIS
parser_vis = subparsers.add_parser('vis', help='Launch simple visualizer on dataset')
parser_vis.add_argument('path', help='Relative or absolute path to directory',
default='.', nargs='?')
# PROC, DOC, CHECK
parser_proc = subparsers.add_parser('proc', help='Data processing')
parser_doc = subparsers.add_parser('doc', help='Data documentation')
parser_check = subparsers.add_parser('check', help='Check/verify data and documentation integrity')
......@@ -52,7 +61,10 @@ if __name__ == "__main__":
log = logging.getLogger(__name__)
if cli_args is None or cli_args.command == 'cli':
DataMan().cmdloop()
try:
dm = DataMan().cmdloop()
except KeyboardInterrupt:
pass
else:
DataMan().onecmd(' '.join(sys.argv[1:]))
......@@ -8,6 +8,7 @@ import cmd
import lib.tools
from lib.constants import LOG_LEVEL_VERBOSE
class DataMan(cmd.Cmd):
"""Command line tool for quick data documentation."""
......@@ -40,6 +41,10 @@ class DataMan(cmd.Cmd):
import lib.dirstats as ds
ds.print_table(ds.gather(path))
def do_vis(self, path):
from vis import vis
vis.run(target='../data/2014-10-30_16-07-29')
def do_exit(self, line):
"Exit"
return True
......@@ -54,10 +59,13 @@ class DataMan(cmd.Cmd):
if __name__ == "__main__":
logging.addLevelName(LOG_LEVEL_VERBOSE, "VERBOSE")
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log = logging.getLogger(__name__)
if len(sys.argv) > 1:
DataMan().onecmd(' '.join(sys.argv[1:]))
else:
DataMan().cmdloop()
try:
dm = DataMan().cmdloop()
except KeyboardInterrupt:
pass
......@@ -18,35 +18,32 @@ import math
from reader import read_record, read_header
# Number of cols and rows in the table.
nrows = 16
ncols = 4
# Number of signals.
m = nrows*ncols
# Number of samples per signal.
# FIXME: Depends on zoom level/sampling rate?
n = 3e4
# Buffer
buf = np.zeros((m, n), dtype=np.float32)
# Dimensions of plot segment/signals
n_rows = 16
n_cols = 4
n_signals = n_rows*n_cols
n_samples = 3e4
# Buffer to store all the pre-loaded signals
buf = np.zeros((n_signals, n_samples), dtype=np.float32)
# Load vertex and fragment shaders
SHADER_PATH = os.path.join(os.path.dirname(__file__), 'shaders')
with open(os.path.join(SHADER_PATH, 'vis.vert')) as vs:
VERT_SHADER = vs.read()
with open(os.path.join(SHADER_PATH, 'vis.frag')) as fs:
FRAG_SHADER = fs.read()
# Color of each vertex
# TODO: make it more efficient by using a GLSL-based color map and the index.
color = np.repeat(np.random.uniform(size=(nrows, 3), low=.1, high=.9),
n*ncols, axis=0).astype(np.float32)
color = np.repeat(np.random.uniform(size=(n_rows, 3), low=.1, high=.9),
n_samples*n_cols, axis=0).astype(np.float32)
# Signal 2D index of each vertex (row and col) and x-index (sample index
# within each signal).
index = np.c_[np.repeat(np.repeat(np.arange(ncols), nrows), n),
np.repeat(np.tile(np.arange(nrows), ncols), n),
np.tile(np.arange(n), m)].astype(np.float32)
with open('shaders/vis.vert') as vs:
VERT_SHADER = vs.read()
with open('shaders/vis.frag') as fs:
FRAG_SHADER = fs.read()
index = np.c_[np.repeat(np.repeat(np.arange(n_cols), n_rows), n_samples),
np.repeat(np.tile(np.arange(n_rows), n_cols), n_samples),
np.tile(np.arange(n_samples), n_signals)].astype(np.float32)
class Vis(app.Canvas):
......@@ -66,8 +63,8 @@ class Vis(app.Canvas):
self.program['a_color'] = color
self.program['a_index'] = index
self.program['u_scale'] = (1., 1.)
self.program['u_size'] = (nrows, ncols)
self.program['u_n'] = n
self.program['u_size'] = (n_rows, n_cols)
self.program['u_n'] = n_samples
gloo.set_viewport(0, 0, *self.physical_size)
......@@ -124,14 +121,14 @@ class Vis(app.Canvas):
"""Handle mouse drag and hover"""
if event.is_dragging:
trail = event.trail()
width = self.size[0]/ncols
height = self.size[1]/nrows
width = self.size[0]/n_cols
height = self.size[1]/n_rows
dx = trail[-1][0]-trail[0][0]
dy = trail[-1][1]-trail[0][1]
if event.button == 1:
shift_signal = dx/width
shift_samples = shift_signal * n
shift_samples = shift_signal * n_samples
shift_offset = int(shift_samples/1024)
self.set_offset(absolute=self.drag_offset-shift_offset)
......@@ -165,9 +162,9 @@ class Vis(app.Canvas):
"""Add some data at the end of each signal (real-time signals)."""
# FIXME: Sample precision positions
# FIXME: Only read in data when needed, not per frame. Duh. :D
for i in range(m):
buf[i, :n] = read_record('data/2014-10-30_16-07-29/106_CH{}.continuous'.format(i+1),
offset=self.offset)[:n]
for i in range(n_signals):
buf[i, :n_samples] = read_record(os.path.join(self.target, '106_CH{}.continuous'.format(i+1)),
offset=self.offset)[:n_samples]
self.program['a_position'].set_data(buf)
if self.running:
......@@ -179,8 +176,12 @@ class Vis(app.Canvas):
gloo.clear()
self.program.draw('line_strip')
def run(*args, **kwargs):
vis = Vis(*args, **kwargs)
app.run()
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
c = Vis(target='data/2014-10-30_16-07-29')
app.run()
run(target='../../data/2014-10-30_16-07-29')
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment