Commit 171a422f authored by Stephen Thompson's avatar Stephen Thompson

Merge branch '1-start'

parents cd951745 cc759cb9
Pipeline #1101 passed with stages
in 5 minutes and 50 seconds
......@@ -2,4 +2,5 @@
omit =
./sksurgerynditracker/_version.py
./sksurgerynditracker/__init__.py
./sksurgerynditracker/__main__.py
\ No newline at end of file
./sksurgerynditracker/example.py
......@@ -107,3 +107,33 @@ deploy docs to production:
- public
dependencies:
- build docs
deploy pip to PyPI:
stage: deploy
when: manual
only:
- tags
environment:
name: PyPI
url: https://pypi.python.org/pypi/sckit-surgerynditracker
tags:
- pip-production
artifacts:
paths:
- dist/
script:
# Install packages required to build/publish
# remove any previous distribution files
- pip install wheel twine setuptools
- rm -rf dist
# bundle installer
- python setup.py bdist_wheel
# Upload to pypi
- twine upload --repository pypi dist/* --username $PYPI_USER --password $PYPI_PASS
......@@ -20,7 +20,7 @@ scikit-surgerynditracker
scikit-surgerynditracker is a python project that does interesting things.
scikit-surgerynditracker is a python interface for Northern Digital (NDI) trackers. It should work with Polaris Vicra, Spectra, and Vega optical trackers and Aurora electromagnetic trackers. Tracking data is output as NumPy arrays.
Author: Stephen Thompson
......@@ -30,12 +30,30 @@ scikit-surgerynditracker is part of the `SNAPPY`_ software project, developed at
Installing
----------
You can pip install directly from the repository as follows:
::
pip install scikit-surgerynditracker
Using
-----
Configuration is done using Python libraries. Tracking data is returned in NumPy arrays.
::
pip install git+https://weisslab.cs.ucl.ac.uk/WEISS/SoftwareRepositories/scikit-surgerynditracker
from sksurgerynditracker.nditracker import NDITracker
SETTINGS = {
"tracker type": "polaris",
"romfiles" : ["../data/8700339.rom"]
}
TRACKER = NDITracker()
TRACKER.connect(SETTINGS)
TRACKER.start_tracking()
print(TRACKER.get_frame()
TRACKER.stop_tracking()
TRACKER.close()
See example.py for a full example
Developing
----------
......
......@@ -24,6 +24,21 @@ Requirements
+------------+--------------------------------------------------------+-------------------------------------+
| 0002 | Package has a version number | No test yet, handled by git. |
+------------+--------------------------------------------------------+-------------------------------------+
| 0003 | Connects and configures, vega, polaris and aurora | |
+------------+--------------------------------------------------------+-------------------------------------+
| 0004 | Configures via a python dictionary | |
+------------+--------------------------------------------------------+-------------------------------------+
| 0005 | Provides get frame to get frame of tracking data | |
+------------+--------------------------------------------------------+-------------------------------------+
| 0006 | Get frame returns data as numpy array | |
+------------+--------------------------------------------------------+-------------------------------------+
| 0007 | Supports multiple tracked objects | |
+------------+--------------------------------------------------------+-------------------------------------+
| 0008 | Provides a method to stream data to file for later | |
| | use. | |
+------------+--------------------------------------------------------+-------------------------------------+
| 0009 | If no tracking available GetFrame Returns NaN | |
+------------+--------------------------------------------------------+-------------------------------------+
......
......@@ -2,5 +2,6 @@
# It is used by pip to manage software dependencies. It is not to be
# confused with the software requirements, which are listed in
# doc/requirements.rst
ndicapi
numpy
six
......@@ -14,30 +14,30 @@ setup(
name='scikit-surgerynditracker',
version=versioneer.get_version(),
cmdclass=versioneer.get_cmdclass(),
description='scikit-surgerynditracker',
description='Interface for Northern Digital (NDI) Trackers with data to NumPy arrays'
long_description=long_description,
url='https://weisslab.cs.ucl.ac.uk/WEISS/SoftwareRepositories/scikit-surgerynditracker',
author='Stephen Thompson',
author_email='YOUR-EMAIL@ucl.ac.uk',
author_email='s.thompson@ucl.ac.uk',
license='BSD-3 license',
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'Intended Audience :: Education',
'Intended Audience :: Healthcare Industry',
'Intended Audience :: Information Technology',
'Intended Audience :: Science/Research',
'License :: OSI Approved :: BSD License',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 3',
'Topic :: Scientific/Engineering :: Information Analysis',
'Topic :: Scientific/Engineering :: Medical Science Apps.',
'Topic :: System :: Hardware',
],
keywords='medical imaging',
......@@ -52,7 +52,7 @@ setup(
install_requires=[
'six>=1.10',
'numpy>=1.11',
'pillow',
'ndicapi>=3.2.0',
],
entry_points={
......
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""scikit-surgerynditracker"""
import sys
if __name__ == "__main__" and not __package__:
# To allow the package's main function to be executed without the -m switch,
# i.e. "python sksurgerynditracker", we have to explicitly set the
# module name and append the parent directory to the sys.path (see PEP 366)
from os import path
__package__ = "sksurgerynditracker" # pylint: disable=redefined-builtin
sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
sys.path.append(path.dirname(path.dirname(__file__)))
# pylint: disable=wrong-import-position
from sksurgerynditracker.ui.sksurgerynditracker_command_line import main
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
#! /user/bin/python
"""Brief example showing how to initialise, configure, and communicate
with NDI Polaris, Vega, and Aurora trackers."""
import time
import six
from sksurgerynditracker.nditracker import NDITracker
#configuration.
SETTINGS_VEGA = {
"tracker type": "vega",
"ip address" : "192.168.2.17",
"port" : 8765,
"romfiles" : [
"../data/8700339.rom",
"../data/something_else.rom"]
}
SETTINGS_POLARIS = {
"tracker type": "polaris",
"romfiles" : [
"../data/8700339.rom"]
}
SETTINGS_AURORA = {
"tracker type": "aurora",
}
SETTINGS_DUMMY = {
"tracker type": "dummy",
}
TRACKER = NDITracker()
TRACKER.connect(SETTINGS_VEGA)
TRACKER.start_tracking()
six.print_(TRACKER.get_tool_descriptions())
for _ in range(20):
six.print_(TRACKER.get_frame())
time.sleep(0.300333)
TRACKER.stop_tracking()
TRACKER.close()
This diff is collapsed.
# coding=utf-8
"""scikit-surgerynditracker"""
# coding=utf-8
"""Command line processing"""
import argparse
from sksurgerynditracker import __version__
from sksurgerynditracker.ui.sksurgerynditracker_demo import run_demo
def main(args=None):
"""Entry point for scikit-surgerynditracker application"""
parser = argparse.ArgumentParser(description='scikit-surgerynditracker')
parser.add_argument("-t", "--text",
required=False,
default="This is scikit-surgerynditracker",
type=str,
help="Text to display")
parser.add_argument("--console", required=False,
action='store_true',
help="If set, scikit-surgerynditracker "
"will not bring up a graphical user interface")
version_string = __version__
friendly_version_string = version_string if version_string else 'unknown'
parser.add_argument(
"-v", "--version",
action='version',
version='scikit-surgerynditracker version ' + friendly_version_string)
args = parser.parse_args(args)
run_demo(args.console, args.text)
# coding=utf-8
"""Hello world demo module"""
import six
def run_demo(console, text):
"""Show message"""
six.print_(text)
if not console:
from tkinter import Tk, Label
root = Tk()
label = Label(root, text=text)
label.pack()
#uncomment root.mainloop() to enter tk main loop.
#Delete any unit tests covering this section first
#though as they will not complete.
#root.mainloop()
return True
......@@ -32,7 +32,7 @@ unsafe-load-any-extension=no
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=numpy
extension-pkg-whitelist=numpy,ndicapy
# Allow optimization of some AST trees. This will activate a peephole AST
# optimizer, which will apply various small optimizations. For instance, it can
......
......@@ -2,39 +2,176 @@
"""scikit-surgerynditracker tests"""
from sksurgerynditracker.ui.sksurgerynditracker_demo import run_demo
import six
# Pytest style
def test_using_pytest_sksurgerynditracker():
console = True
assert run_demo(console, "Hello World") == True
# Disable this test if root.mainloop is uncommented in
# run_demo()
def test_using_pytest_cookienewwithgitinit_withTK():
try:
import tkinter
try:
console=False
assert run_demo(console, "Hello World") == True
except tkinter.TclError:
six.print_("Got TCL error, probably no DISPLAY set, that's OK.")
assert True
except:
six.print_("Got another error (not TCL), that's not OK.")
assert False
except ModuleNotFoundError:
six.print_("Got module not found on tkinter, please check your python installation")
#we're not trying to test whether we have tkinter so this is ok
assert True
except ImportError:
six.print_("Got import error on tkinter, please check your python installation")
#we're not trying to test whether we have tkinter so this is ok
assert True
except:
assert False
import pytest
from sksurgerynditracker.nditracker import NDITracker
#configuration.
SETTINGS_VEGA = {
"tracker type": "vega",
"ip address" : "192.168.2.17",
"port" : 8765,
"romfiles" : [
"../data/something_else.rom",
"../data/8700339.rom"]
}
SETTINGS_POLARIS = {
"tracker type": "polaris",
"romfiles" : [
"../data/something_else.rom",
"../data/8700339.rom"]
}
SETTINGS_AURORA = {
"tracker type": "aurora",
}
SETTINGS_DUMMY = {
"tracker type": "dummy",
}
def test_connect():
#what testing can we do with out being attached to a tracker?
#What testing can we do when we are attached to a tracker?
#We could build a fake ndi tracker, that listens on a port
#and responds appropriately.
tracker = NDITracker()
tracker.connect(SETTINGS_DUMMY)
tracker.close()
def test_connect_network():
tracker = NDITracker()
with pytest.raises(IOError):
tracker.connect(SETTINGS_VEGA)
with pytest.raises(ValueError):
tracker.close()
def test_connect_serial():
tracker = NDITracker()
with pytest.raises(IOError):
tracker.connect(SETTINGS_POLARIS)
with pytest.raises(ValueError):
tracker.close()
def test_configure():
tracker = NDITracker()
no_rom = {
"tracker type": "polaris",
}
with pytest.raises(KeyError):
tracker._configure(no_rom)
bad_tracker = {
"tracker type": "optotrack",
}
with pytest.raises(ValueError):
tracker._configure(bad_tracker)
no_ip = {
"tracker type": "vega",
"romfiles": "[rom]"
}
with pytest.raises(KeyError):
tracker._configure(no_ip)
no_port = {
"tracker type": "vega",
"ip address": "tracker",
"romfiles": "[rom]"
}
tracker._configure(no_port)
aurora = { "tracker type": "aurora" }
tracker._configure(aurora)
aurora_sp = { "tracker type": "aurora",
"serial_port": "1"}
tracker._configure(aurora_sp)
aurora_np = { "tracker type": "aurora",
"ports to probe": "50"}
tracker._configure(aurora_np)
def test_close():
with pytest.raises(ValueError):
tracker = NDITracker()
tracker.close()
def test_read_sroms_from_file():
tracker = NDITracker()
tracker.connect(SETTINGS_DUMMY)
with pytest.raises(ValueError):
tracker._read_sroms_from_file()
tracker.close()
def test_initialise_ports():
tracker = NDITracker()
tracker.connect(SETTINGS_DUMMY)
with pytest.raises(ValueError):
tracker._initialise_ports()
tracker.close()
def test_enable_tools():
tracker = NDITracker()
tracker.connect(SETTINGS_DUMMY)
with pytest.raises(ValueError):
tracker._enable_tools()
tracker.close()
def test_get_frame():
tracker = NDITracker()
tracker.connect(SETTINGS_DUMMY)
data = tracker.get_frame()
assert data.shape == (0,9)
assert data.dtype == 'float64'
dummy_two_rom = {
"tracker type": "dummy",
"romfiles" : [
"../data/something_else.rom",
"../data/8700339.rom"]
}
tracker.connect(dummy_two_rom)
data = tracker.get_frame()
assert data.shape == (2,9)
assert data.dtype == 'float64'
def test_get_tool_descriptions():
tracker = NDITracker()
tracker.connect(SETTINGS_DUMMY)
descriptions = tracker.get_tool_descriptions()
assert len(descriptions) == 0
dummy_two_rom = {
"tracker type": "dummy",
"romfiles" : [
"../data/something_else.rom",
"../data/8700339.rom"]
}
tracker.connect(dummy_two_rom)
descriptions = tracker.get_tool_descriptions()
assert len(descriptions) == 2
def test_start_tracking():
tracker = NDITracker()
tracker.connect(SETTINGS_DUMMY)
with pytest.raises(ValueError):
tracker.start_tracking()
tracker.close()
def test_stop_tracking():
tracker = NDITracker()
tracker.connect(SETTINGS_DUMMY)
with pytest.raises(ValueError):
tracker.stop_tracking()
tracker.close()
def test_check_for_errors():
tracker = NDITracker()
tracker.connect(SETTINGS_DUMMY)
with pytest.raises(ValueError):
tracker._check_for_errors("dummy error")
tracker.close()
......@@ -13,7 +13,7 @@ deps=-rrequirements-dev.txt
whitelist_externals=coverage,pip
# See .coveragerc for list of omitted files
commands = coverage erase
coverage run -a --source ./sksurgerynditracker --omit sksurgerynditracker/ui/sksurgerynditracker_command_line.py -m pytest
coverage run -a --source ./sksurgerynditracker -m pytest
coverage report -m
[testenv:lint]
......@@ -29,7 +29,7 @@ commands = sphinx-build -M html . build
[testenv:installer]
basepython=python3.6
commands=pyinstaller --onefile sksurgerynditracker.py --noconfirm --windowed
commands=python -c "print('Installer not needed for this project.')"
[testenv:pip2]
basepython=python2.7
......
Markdown is supported
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