Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions .github/workflows/ci_python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Test Python

on:
push:
branches: [ master, development ]
branches: [ master, development, experimental, test* ]
pull_request:
branches: [ master, development ]
branches: [ master, development, experimental, test* ]

jobs:
build:
Expand All @@ -13,13 +13,13 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: ["3.9", "3.10", "3.11", "3.12"]

steps:

- uses: actions/checkout@v2
- uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}

Expand All @@ -31,6 +31,16 @@ jobs:
- name: Install Python package
run: |
cd src/Python
python setup.py install
pip install .

- name: Run tests
run: |
cd src/Python/tests
python tests.py
python diagnostic_test.py ../../../tests/minimax.wcon

- name: Final version info
run: |
pip list


6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Random editor stuff
*~
*.swp

# Python byte-compiled / optimized / DLL files
*.pyc
Expand All @@ -9,9 +10,14 @@ src/Python/dist/*
src/Python/tests/test_chunk*
src/Python/wcon.egg*
.pypirc
openworm/

#Matlab
*.asv

# Scala
src/scala/target/*
src/scala/**/target/*

/src/Python/example_saved_file.WCON
/src/Python/wcon/wcon_schema.json
17 changes: 17 additions & 0 deletions src/Python/Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
pandas = "*"
six = "*"
numpy = "*"
psutil = "*"
jsonschema = "*"
scipy = "*"

[dev-packages]

[requires]
python_version = "3.9"
395 changes: 395 additions & 0 deletions src/Python/Pipfile.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/Python/examples/view_wcon.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
sys.path.append('..')
from wcon import WCONWorms, MeasurementUnit

file_name = 'asic-1 (ok415) on food L_2010_07_08__11_46_40___7___5.wcon'
file_name = '../../../tests/minimax.wcon'
w = WCONWorms.load_from_file(file_name)
21 changes: 21 additions & 0 deletions src/Python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[project]
name = "wcon"
version = "1.1.0"
authors = [
{ name="Kerr, R; Brown, A; Currie, M; OpenWorm", email="ichoran@gmail.com" },
]
description = "Worm tracker Commons Object Notation"
readme = "README.md"
requires-python = ">=3.9"
classifiers = [
'Development Status :: 4 - Beta',
'Intended Audience :: Science/Research',
'Topic :: Scientific/Engineering :: Bio-Informatics',
"Programming Language :: Python :: 3",
"Operating System :: OS Independent",
]
license = "MIT"

[project.urls]
Homepage = "https://github.com/openworm/tracker-commons"
Issues = "https://github.com/openworm/tracker-commons/issues"
6 changes: 6 additions & 0 deletions src/Python/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
six
jsonschema
numpy
pandas
psutil
scipy
14 changes: 11 additions & 3 deletions src/Python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from codecs import open
from os import path
import os
import shutil
exec(open('wcon/version.py').read())

here = path.abspath(path.dirname(__file__))
Expand All @@ -24,7 +25,13 @@
with open(readme_path, encoding='utf-8') as f:
long_description += f.read()

print(os.listdir('.')) # DEBUG
# The canonical wcon_schema.json lives at the repository root so it can be
# shared by every language implementation. setuptools cannot package files
# from outside the package directory, so copy it into wcon/ at build time.
repo_schema = path.join(here, '..', '..', 'wcon_schema.json')
pkg_schema = path.join(here, 'wcon', 'wcon_schema.json')
if path.exists(repo_schema):
shutil.copyfile(repo_schema, pkg_schema)

setup(
name='wcon',
Expand All @@ -51,8 +58,9 @@
],
keywords='C. elegans worm tracking',
packages=['wcon'],
package_data={'': ['../../wcon_schema.json']},
install_requires=['jsonschema', 'six', 'numpy', 'scipy<=0.17.1']
package_data={'wcon': ['wcon_schema.json']},
include_package_data=True,
install_requires=['jsonschema', 'six', 'scipy', 'pandas', 'psutil'],
# Actually also requires numpy, scipy and numpy but I don't want to force
# pip to install these since pip is bad at that for those packages.
)
Binary file removed src/Python/tests/.bbb.wcon.swp
Binary file not shown.
24 changes: 23 additions & 1 deletion src/Python/tests/diagnostic_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
idx = pd.IndexSlice
import numpy as np
import time
import pprint as pp

sys.path.append('..')
dir_path = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(dir_path, '..'))
from wcon import WCONWorms, MeasurementUnit
from wcon.measurement_unit import MeasurementUnitAtom

Expand Down Expand Up @@ -51,6 +53,12 @@ def timing_function():
validate_against_schema=False)
print("Time to load w1: " + str(timing_function() - start_time))

print(" ------- W1 has " + str(len(w1.data)) + " rows and " +
str(len(w1.data.columns)) + " columns")

print(pp.pformat(w1.data_as_odict))
print (' -------- ')

# Save these worm tracks to a file, then load that file
test_path = 'test.wcon'
start_time = timing_function()
Expand All @@ -62,6 +70,12 @@ def timing_function():
validate_against_schema=False)
print("Time to load w2: " + str(timing_function() - start_time))

print(" ------- W2 has " + str(len(w2.data)) + " rows and " +
str(len(w2.data.columns)) + " columns")

print(pp.pformat(w2.data_as_odict))
print (' -------- ')

# x1 = w1.data.loc[:, idx[0, 'x', 0]].fillna(0)
# x2 = w2.data.loc[:, idx[0, 'x', 0]].fillna(0)
# cmm = np.flatnonzero(x1 != x2)
Expand All @@ -76,6 +90,14 @@ def timing_function():
# "id" first in a data segment, etc.)
w3 = WCONWorms.load_from_file(test_path,
validate_against_schema=False)


print(" ------- W3 has " + str(len(w3.data)) + " rows and " +
str(len(w3.data.columns)) + " columns")

print(pp.pformat(w3.data_as_odict))
print (' -------- ')

assert(w2 == w3)
assert(w1 == w2)
assert(w1 == w3)
Expand Down
19 changes: 11 additions & 8 deletions src/Python/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@
import shutil
from scipy.constants import pi

sys.path.append('..')
dir_path = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(dir_path, '..'))
from wcon import WCONWorms, MeasurementUnit
from wcon.measurement_unit import MeasurementUnitAtom


def setUpModule():
# If the wcon module is installed via pip, wcon_schema.json is included
# in the proper place. In the git repo it is not, however, so to test
# we must copy it over temporarily, then remove it once tests are done.
shutil.copyfile('../../../wcon_schema.json', '../wcon/wcon_schema.json')
# we must copy it over temporarily, then remove it once tests are done.
shutil.copyfile(os.path.join(dir_path, '..', '..', '..', 'wcon_schema.json'), os.path.join(dir_path, '..', 'wcon', 'wcon_schema.json'))


def tearDownModule():
os.remove('../wcon/wcon_schema.json')
os.remove(os.path.join(dir_path, '..', 'wcon', 'wcon_schema.json'))


def flatten(list_of_lists):
Expand All @@ -41,7 +41,7 @@ def flatten(list_of_lists):
for element in list_of_lists:
# If it's iterable but not a string or bytes, then recurse, otherwise
# we are at a "leaf" node of our traversal
if(isinstance(element, collections.Iterable) and
if(isinstance(element, collections.abc.Iterable) and
not isinstance(element, (str, bytes))):
for sub_element in flatten(element):
yield sub_element
Expand Down Expand Up @@ -192,7 +192,9 @@ def _validate_from_schema(self, wcon_string):
except AttributeError:
# Only load _wcon_schema if this method gets called. Once
# it's loaded, though, persist it in memory and don't lose it
with open("../../../wcon_schema.json", "r") as wcon_schema_file:
wcon_schema_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
'..', '..', '..', 'wcon_schema.json'))
with open(wcon_schema_path, "r") as wcon_schema_file:
self._wcon_schema = json.loads(wcon_schema_file.read())

# Now that the schema has been loaded, we can try again
Expand All @@ -204,7 +206,8 @@ def test_schema(self):
self._validate_from_schema(basic_wcon)

def test_equality_operator(self):
JSON_path = '../../../tests/minimax.wcon'
JSON_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
'..', '..', '..', 'tests', 'minimax.wcon'))
w2 = WCONWorms.load_from_file(JSON_path)
w2.units['y'] = MeasurementUnit.create('m')
w2data = w2.data.copy()
Expand Down
17 changes: 14 additions & 3 deletions src/Python/wcon/measurement_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
import operator as op
from scipy.constants import convert_temperature, pi

def F2C(val):
return convert_temperature(val, 'F', 'C')
def C2F(val):
return convert_temperature(val, 'C', 'F')
def K2C(val):
return convert_temperature(val, 'K', 'C')
def C2K(val):
return convert_temperature(val, 'C', 'K')

def C2C(x):
"""
Expand Down Expand Up @@ -637,12 +645,15 @@ def _create_from_atomic(cls, unit_string):
@classmethod
def _create_from_node(cls, node):
"""
node: is ast.Num or ast.BinOp or ast.UnaryOp or ast.Str or ast.Name
node: is ast.Constant (numeric) or ast.BinOp or ast.UnaryOp or ast.Name
The expression to be transformed into a MeasurementUnit

"""
if isinstance(node, ast.Num): # <number>
n = node.n
# ast.Num was deprecated in Python 3.8 and removed in 3.14;
# ast.Constant now represents all literal values.
if isinstance(node, ast.Constant) and isinstance(
node.value, (int, float)): # <number>
n = node.value
assert(n != 0) # A unit cannot have zero in the expression

u = cls()
Expand Down
2 changes: 1 addition & 1 deletion src/Python/wcon/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
# 2) we can import it in setup.py for the same reason
# 3) we can import it into your module module
# (from http://stackoverflow.com/questions/458550/)
__version__ = '1.1.0'
__version__ = '1.2.1'
Loading
Loading