Skip to content

Commit

Permalink
Change minimum versions and remove compatibility fixes (soft-matter#656)
Browse files Browse the repository at this point in the history
* Test against numba 0.45 on Py37

* Increase minimum versions

* Bump travis (doc build)

* Bump doc build env
  • Loading branch information
caspervdw authored Apr 2, 2021
1 parent a8c76d8 commit bfc6cb1
Show file tree
Hide file tree
Showing 12 changed files with 28 additions and 120 deletions.
11 changes: 1 addition & 10 deletions .github/workflows/test-pip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,14 @@ jobs:
fail-fast: false
matrix:
include:
# "Legacy" environments: oldest supported versions, without and with optional dependencies
- python: 3.5
display_name: "no optional deps"
numpy: "numpy==1.13.*"
deps: "scipy==0.19.* matplotlib==2.0.* pandas==0.20.* pyyaml"
- python: 3.5
display_name: "no numba"
numpy: "numpy==1.13.*"
deps: "scipy==0.19.* matplotlib==2.0.* pillow==4.2.* pandas==0.20.* scikit-image==0.13.* tables==3.3.* scikit-learn==0.19.* pyyaml==3.12"
# 2017
- python: 3.6
numpy: "numpy==1.14.*"
deps: "scipy==1.1.* matplotlib==2.1.* pillow==4.3.* pandas==0.22.* scikit-image==0.13.* tables==3.4.* scikit-learn==0.19.* pyyaml==3.12 numba==0.32.* llvmlite==0.17.*"
# 2018
- python: 3.7
numpy: "numpy==1.16.*"
deps: "scipy==1.3.* matplotlib==2.2.* pillow==5.3.* pandas==0.23.* scikit-image==0.14.* tables==3.5.* scikit-learn==0.20.* pyyaml==3.13 numba==0.39.* llvmlite==0.24."
deps: "scipy==1.3.* matplotlib==2.2.* pillow==5.3.* pandas==0.23.* scikit-image==0.14.* tables==3.5.* scikit-learn==0.20.* pyyaml==3.13 numba==0.45.* llvmlite==0.29.*"
# 2019
- python: 3.8
numpy: "numpy==1.18.*"
Expand Down
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ language: python

jobs:
include:
# Python 3, circa September 2017 (Anaconda 5.0.0), used for building docs
- python: "3.5"
env: DEPS="numpy=1.13.1 scipy=0.19.1 matplotlib=2.0.2 pillow=4.2.1 pandas=0.20.3 scikit-image=0.13.0 pytables numba=0.35.0 scikit-learn=0.19.0 pyyaml" BUILD_DOCS=true
# Note: Apr 2, 2021. This is only used for building the docs now, testing happens in Github actions.
- python: "3.8"
env: DEPS="numpy scipy matplotlib pillow pandas scikit-image pytables numba scikit-learn pyyaml" BUILD_DOCS=true

install:
- conda update --yes conda
Expand All @@ -28,7 +28,7 @@ script:
- |
if [ $BUILD_DOCS == true ]; then
conda config --append channels conda-forge
conda install --yes ipython=5.1.0 sphinx=1.4.8 numpydoc=0.6.0 nbconvert=4.2.0 sphinx_bootstrap_theme=0.4
conda install --yes ipython sphinx numpydoc nbconvert sphinx_bootstrap_theme
cd $TRAVIS_BUILD_DIR/..
git clone https://github.com/soft-matter/trackpy-examples.git
cd trackpy/doc
Expand Down
8 changes: 3 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,14 @@
author = "Trackpy Contributors",
author_email = "[email protected]",
url = "https://github.com/soft-matter/trackpy",
install_requires = ['numpy>=1.9', 'scipy>=0.14',
'pandas>=0.15', 'pyyaml', 'matplotlib'],
python_requires=">=3.5",
install_requires = ['numpy>=1.14', 'scipy>=1.1', 'pandas>=0.22', 'pyyaml', 'matplotlib'],
python_requires=">=3.6",
classifiers=[
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
],
packages = ['trackpy', 'trackpy.refine', 'trackpy.linking', 'trackpy.locate_functions'],
long_description = descr,
Expand Down
3 changes: 2 additions & 1 deletion trackpy/linking/legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

import numpy as np
import pandas as pd
from scipy.spatial import cKDTree

from ..try_numba import NUMBA_AVAILABLE
from ..utils import pandas_sort, cKDTree, validate_tuple, is_isotropic
from ..utils import pandas_sort, validate_tuple, is_isotropic
from .utils import (TrackUnstored, points_to_arr, UnknownLinkingError,
SubnetOversizeException)
from .subnetlinker import (recursive_linker_obj, nonrecursive_link, drop_link,
Expand Down
3 changes: 2 additions & 1 deletion trackpy/linking/subnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

import numpy as np
import pandas as pd
from scipy.spatial import cKDTree

from .utils import points_to_arr
from ..utils import default_pos_columns, cKDTree
from ..utils import default_pos_columns

try:
from sklearn.neighbors import BallTree
Expand Down
5 changes: 2 additions & 3 deletions trackpy/motion.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

import warnings
from warnings import warn
from .utils import (pandas_sort, pandas_concat, pandas_rolling,
guess_pos_columns)
from .utils import pandas_sort, pandas_concat, guess_pos_columns


def msd(traj, mpp, fps, max_lagtime=100, detail=False, pos_columns=None):
Expand Down Expand Up @@ -287,7 +286,7 @@ def compute_drift(traj, smoothing=0, pos_columns=None):
mask = (f_diff['particle'] == 0) & (f_diff['frame_diff'] == 1)
dx = f_diff.loc[mask, list(pos_columns) + ['frame']].groupby('frame').mean()
if smoothing > 0:
dx = pandas_rolling(dx, smoothing, min_periods=0)
dx = dx.rolling(smoothing, min_periods=0).mean()
return dx.cumsum()


Expand Down
3 changes: 2 additions & 1 deletion trackpy/static.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .utils import cKDTree, guess_pos_columns
from scipy.spatial import cKDTree
from .utils import guess_pos_columns
import numpy as np
from pandas import DataFrame

Expand Down
3 changes: 2 additions & 1 deletion trackpy/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import numpy as np
from numpy.testing import assert_allclose, assert_equal, assert_array_equal
import trackpy as tp
from trackpy.utils import cKDTree, pandas_sort, make_pandas_strict
from scipy.spatial import cKDTree
from trackpy.utils import pandas_sort, make_pandas_strict
from trackpy.artificial import SimulatedImage
from matplotlib.pyplot import imread

Expand Down
Binary file not shown.
3 changes: 1 addition & 2 deletions trackpy/tests/test_legacy_linking.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
from trackpy.linking.legacy import (link, link_df, link_df_iter,
PointND, Hash_table, strip_diagnostics,
SubnetOversizeException)
from trackpy.utils import (is_pandas_since_016,
pandas_sort, pandas_concat, validate_tuple)
from trackpy.utils import pandas_sort, pandas_concat, validate_tuple
from trackpy.tests.common import StrictTestCase, assert_traj_equal


Expand Down
25 changes: 8 additions & 17 deletions trackpy/tests/test_reproducibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,17 @@
import numpy as np
import pandas as pd
from numpy.testing import assert_array_equal, assert_allclose
from scipy.spatial import cKDTree

import trackpy as tp
from trackpy.preprocessing import invert_image
from trackpy.utils import cKDTree, pandas_iloc, is_scipy_since_100
from trackpy.tests.common import TrackpyImageSequence
from trackpy.tests.common import assert_traj_equal, StrictTestCase

path, _ = os.path.split(os.path.abspath(__file__))


# The reproducibility tests differ depending on the Scipy version, because of
# changed rounding properties of `scipy.ndimage.filters.uniform_filter1d`. These
# changes propagate via trackpy's preprocessing into the tested values in the
# following tests: `test_find_bp`, `test_locate`, `test_refine`, and
# `test_characterize`. See GH issue #459.
if is_scipy_since_100:
reproduce_fn = 'reproducibility_v0.4.npz'
else:
reproduce_fn = 'reproducibility_v0.4_pre_scipy_v1.0.npz'
reproduce_fn = os.path.join(path, 'data', reproduce_fn)
reproduce_fn = os.path.join(path, 'data', 'reproducibility_v0.4.npz')


def compare_pos_df(actual, expected, pos_atol=0.001, lost_atol=1):
Expand Down Expand Up @@ -53,12 +44,12 @@ def compare_pos_df(actual, expected, pos_atol=0.001, lost_atol=1):
i_appeared1 = np.argwhere(~np.in1d(np.arange(len(coords1)),
np.concatenate(
[i_equal0, i_dev0]))).ravel()
lost0.append(pandas_iloc(expected_frame, i_lost0).index.values)
appeared1.append(pandas_iloc(actual_frame, i_appeared1).index.values)
dev0.append(pandas_iloc(expected_frame, i_dev0).index.values)
dev1.append(pandas_iloc(actual_frame, i_dev1).index.values)
equal0.append(pandas_iloc(expected_frame, i_equal0).index.values)
equal1.append(pandas_iloc(actual_frame, i_equal1).index.values)
lost0.append(expected_frame.iloc[i_lost0].index.values)
appeared1.append(actual_frame.iloc[i_appeared1].index.values)
dev0.append(expected_frame.iloc[i_dev0].index.values)
dev1.append(actual_frame.iloc[i_dev1].index.values)
equal0.append(expected_frame.iloc[i_equal0].index.values)
equal1.append(actual_frame.iloc[i_equal1].index.values)

return np.concatenate(lost0), np.concatenate(appeared1), \
(np.concatenate(dev0), np.concatenate(dev1)), \
Expand Down
76 changes: 1 addition & 75 deletions trackpy/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,51 +17,13 @@

import trackpy

# Set is_pandas_since_016 for use elsewhere.
# Pandas >= 0.16.0 lets us check if a DataFrame is a view.
try:
is_pandas_since_016 = (LooseVersion(pd.__version__) >=
LooseVersion('0.16.0'))
except ValueError: # Probably a development version
is_pandas_since_016 = True

try:
is_pandas_since_017 = (LooseVersion(pd.__version__) >=
LooseVersion('0.17.0'))
except ValueError: # Probably a development version
is_pandas_since_017 = True

try:
is_pandas_since_018 = (LooseVersion(pd.__version__) >=
LooseVersion('0.18.0'))
except ValueError: # Probably a development version
is_pandas_since_018 = True
try:
is_pandas_since_023 = (LooseVersion(pd.__version__) >=
LooseVersion('0.23.0'))
except ValueError: # Probably a development version
is_pandas_since_023 = True

# Wrap the scipy cKDTree to work around a bug in scipy 0.18.0
try:
is_scipy_018 = LooseVersion(scipy.__version__) == LooseVersion('0.18.0')
except ValueError: # Probably a development version
is_scipy_018 = False


if is_scipy_018:
from scipy.spatial import KDTree as cKDTree
warnings.warn("Due to a bug in Scipy 0.18.0, the (faster) cKDTree cannot "
"be used. For better linking performance, upgrade or "
"downgrade scipy.")
else:
from scipy.spatial import cKDTree

try:
is_scipy_since_100 = LooseVersion(scipy.__version__) >= LooseVersion('1.0.0')
except ValueError: # Probably a development version
is_scipy_since_100 = True

# Emit warnings in refine.least_squares for scipy 1.5
try:
is_scipy_15 = LooseVersion("1.5.0") <= LooseVersion(scipy.__version__) < LooseVersion('1.6.0')
Expand Down Expand Up @@ -312,11 +274,8 @@ def quiet(suppress=True):
else:
trackpy.logger.setLevel(logging.INFO)

def _pandas_sort_pre_017(df, by, *args, **kwargs):
"""Use sort() to sort a DataFrame"""
return df.sort(*args, columns=by, **kwargs)

def _pandas_sort_post_017(df, by, *args, **kwargs):
def pandas_sort(df, by, *args, **kwargs):
"""
Use sort_values() to sort a DataFrame
This raises a ValueError if the given value is both
Expand All @@ -330,39 +289,6 @@ def _pandas_sort_post_017(df, by, *args, **kwargs):
df.index.name += '_index'
return df.sort_values(*args, by=by, **kwargs)

if is_pandas_since_017:
pandas_sort = _pandas_sort_post_017
else:
pandas_sort = _pandas_sort_pre_017

def _pandas_iloc_pre_016(df, inds):
"""Workaround for bug, iloc with empty list, in pandas < 0.16"""
if len(inds) > 0:
return df.iloc[inds]
else:
return df.iloc[:0]

def _pandas_iloc_since_016(df, inds):
return df.iloc[inds]

if is_pandas_since_016:
pandas_iloc = _pandas_iloc_since_016
else:
pandas_iloc = _pandas_iloc_pre_016

def _pandas_rolling_pre_018(df, window, *args, **kwargs):
"""Use rolling_mean() to compute a rolling average"""
return pd.rolling_mean(df, window, *args, **kwargs)

def _pandas_rolling_since_018(df, window, *args, **kwargs):
"""Use rolling() to compute a rolling average"""
return df.rolling(window, *args, **kwargs).mean()

if is_pandas_since_018:
pandas_rolling = _pandas_rolling_since_018
else:
pandas_rolling = _pandas_rolling_pre_018


def _pandas_concat_post_023(*args, **kwargs):
"""Pass sort = False. Breaks API by not sorting, but we don't care. """
Expand Down

0 comments on commit bfc6cb1

Please sign in to comment.