From 0f339ff14a0d5ba967f0f41474a3bb24d1860241 Mon Sep 17 00:00:00 2001 From: Jiri Borovec Date: Fri, 27 Dec 2019 09:42:36 +0100 Subject: [PATCH] drop GCO dependency * absolute imports * split py2 py3 reqs * CI: min-max build * fix skimage region prop. * general flake8 config * CI: nose -> pytest * fix numpy loads * fix docs links --- .travis.yml | 46 +++++++++++++------ MANIFEST.in | 1 + circle.yml | 4 +- docs/source/conf.py | 6 ++- .../run_center_candidate_training.py | 4 +- .../run_ovary_egg-segmentation.py | 4 +- .../run_segm_slic_classif_graphcut.py | 2 +- imsegm/__init__.py | 2 +- imsegm/annotation.py | 2 +- imsegm/classification.py | 4 +- imsegm/ellipse_fitting.py | 6 +-- imsegm/graph_cuts.py | 12 +++-- imsegm/labeling.py | 2 +- imsegm/pipelines.py | 12 ++--- imsegm/region_growing.py | 27 ++++++----- imsegm/utilities/data_io.py | 41 ++++++++++------- imsegm/utilities/data_samples.py | 3 +- requirements-py27.txt | 16 +++++++ requirements.txt | 20 ++++---- setup.cfg | 12 ++++- setup.py | 4 +- tests/requirements.txt | 3 +- tests/test_region-growing.py | 4 +- 23 files changed, 152 insertions(+), 85 deletions(-) create mode 100644 requirements-py27.txt diff --git a/.travis.yml b/.travis.yml index 11c791e3..28092b7d 100755 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,6 @@ # See doc/travis_notes.txt for some guidelines -dist: xenial # Ubuntu 16.04 - env: global: - CODACY_PROJECT_TOKEN=ea6533a96dfb4b6a9b6b45fc134fabdf @@ -14,39 +12,57 @@ env: language: python -sudo: false - -python: - - 2.7 - # - 3.4 # will be deprecated for pandas - - 3.5 - - 3.6 - - 3.7 +matrix: + include: + - dist: xenial # Ubuntu 16.04 + python: 2.7 + - dist: xenial # Ubuntu 16.04 + python: 3.5 + - dist: xenial # Ubuntu 16.04 + python: 3.6 + env: MIN_REQUIREMENTS=1 + #- dist: xenial # Ubuntu 16.04 + # python: 3.7 + # env: MIN_REQUIREMENTS=1 + - dist: bionic # Ubuntu 18.04 + python: 3.6 + - dist: bionic # Ubuntu 18.04 + python: 3.7 # See http://docs.travis-ci.com/user/caching/#pip-cache cache: pip before_install: - pip install --upgrade pip + # rewrite all minimal requirements as strict + - if [ "$TRAVIS_PYTHON_VERSION" == "2.7" ]; then + cp requirements-py27.txt requirements-ci.txt ; + else if [[ "${MIN_REQUIREMENTS}" == "1" ]]; then + python -c "req = open('requirements.txt').read().replace('>', '=') ; open('requirements-ci.txt', 'w').write(req)" ; + else + cp requirements.txt requirements-ci.txt ; + fi + fi install: - mkdir libs - - pip install -r requirements.txt + - pip install -r requirements-ci.txt -U - pip install -r ./tests/requirements.txt - pip list before_script: + - rm requirements-ci.txt - mkdir output && mkdir results - gcc --version ; python --version ; pip --version ; pwd ; ls -l - check-manifest - - python setup.py check -m -s + - python setup.py check --metadata --strict script: - python setup.py build_ext --inplace # - pytest imsegm -v --doctest-modules - - nosetests imsegm tests -v --exe --with-doctest --with-xunit --with-coverage --cover-package=imsegm - - flake8 . --ignore=E402,E731 --max-line-length=100 - - python setup.py install + - coverage run -m py.test imsegm tests --doctest-modules --flake8 + # - nosetests imsegm tests -v --exe --with-doctest --with-xunit --with-coverage --cover-package=imsegm + - python setup.py install --dry-run after_success: - codecov # public repository on Travis CI diff --git a/MANIFEST.in b/MANIFEST.in index 8935eaae..9a817a8f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -11,6 +11,7 @@ include LICENSE # Include the Requirements include requirements.txt +include requirements-py27.txt # Include package recursive-include imsegm *.py *.pyx diff --git a/circle.yml b/circle.yml index 534e578e..4737dbea 100755 --- a/circle.yml +++ b/circle.yml @@ -22,8 +22,8 @@ references: unset DISPLAY mkdir output && mkdir results && mkdir test-reports coverage run --source imsegm -m py.test imsegm tests -v --doctest-modules --junitxml=test-reports/pytest_junit.xml - python setup.py check -m -s - flake8 . --ignore=E402,E731 --max-line-length=100 + python setup.py check --metadata --strict + flake8 . build_project: &build_project run: diff --git a/docs/source/conf.py b/docs/source/conf.py index 8e4b9515..69d01881 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -295,7 +295,7 @@ def find_source(): obj = getattr(obj, part) fname = inspect.getsourcefile(obj) # https://github.com/rtfd/readthedocs.org/issues/5735 - if any([s in fname for s in ('readthedocs', 'checkouts')]): + if any([s in fname for s in ('readthedocs', 'rtfd', 'checkouts')]): path_top = os.path.abspath(os.path.join('..', '..', '..')) fname = os.path.relpath(fname, start=path_top) else: @@ -313,6 +313,10 @@ def find_source(): # import subprocess # tag = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE, # universal_newlines=True).communicate()[0][:-1] + branch = filename.split('/')[0] + # do mapping from latest tags to master + branch = {'latest': 'master', 'stable': 'master'}.get(branch, branch) + filename = '/'.join([branch] + filename.split('/')[1:]) return "https://github.com/%s/%s/blob/%s" \ % (github_user, github_repo, filename) diff --git a/experiments_ovary_centres/run_center_candidate_training.py b/experiments_ovary_centres/run_center_candidate_training.py index dbb5b9f4..9fc09002 100755 --- a/experiments_ovary_centres/run_center_candidate_training.py +++ b/experiments_ovary_centres/run_center_candidate_training.py @@ -249,7 +249,7 @@ def load_image_segm_center(idx_row, path_out=None, dict_relabel=None): seg_ext = os.path.splitext(os.path.basename(row_path['path_segm']))[-1] if seg_ext == '.npz': - with np.load(row_path['path_segm']) as npzfile: + with np.load(row_path['path_segm'], allow_pickle=True) as npzfile: segm = npzfile[npzfile.files[0]] if dict_relabel is not None: segm = seg_lbs.merge_probab_labeling_2d(segm, dict_relabel) @@ -620,7 +620,7 @@ def load_dump_data(path_dump_data): logging.info('loading dumped data "%s"', path_dump_data) # with open(os.path.join(path_out, NAME_DUMP_TRAIN_DATA), 'r') as f: # dict_data = pickle.load(f) - npz_file = np.load(path_dump_data, encoding='bytes') + npz_file = np.load(path_dump_data, encoding='bytes', allow_pickle=True) dict_imgs = dict(npz_file['dict_images'].tolist()) dict_segms = dict(npz_file['dict_segms'].tolist()) dict_slics = dict(npz_file['dict_slics'].tolist()) diff --git a/experiments_ovary_detect/run_ovary_egg-segmentation.py b/experiments_ovary_detect/run_ovary_egg-segmentation.py index d4f36a98..3254cf8a 100755 --- a/experiments_ovary_detect/run_ovary_egg-segmentation.py +++ b/experiments_ovary_detect/run_ovary_egg-segmentation.py @@ -521,7 +521,7 @@ def segment_rg2sp_greedy(slic, seg, centers, labels_fg_prob, path_model, dict_thresholds=RG2SP_THRESHOLDS, debug_export=''): """ wrapper for region growing method with some debug exporting """ if os.path.splitext(path_model)[-1] == '.npz': - shape_model = np.load(path_model) + shape_model = np.load(path_model, allow_pickle=True) else: shape_model = pickle.load(open(path_model, 'rb')) dict_debug = dict() if os.path.isdir(debug_export) else None @@ -550,7 +550,7 @@ def segment_rg2sp_graphcut(slic, seg, centers, labels_fg_prob, path_model, dict_thresholds=RG2SP_THRESHOLDS, debug_export=''): """ wrapper for region growing method with some debug exporting """ if os.path.splitext(path_model)[-1] == '.npz': - shape_model = np.load(path_model) + shape_model = np.load(path_model, allow_pickle=True) else: shape_model = pickle.load(open(path_model, 'rb')) dict_debug = dict() if os.path.isdir(debug_export) else None diff --git a/experiments_segmentation/run_segm_slic_classif_graphcut.py b/experiments_segmentation/run_segm_slic_classif_graphcut.py index 44b50e66..9836b209 100644 --- a/experiments_segmentation/run_segm_slic_classif_graphcut.py +++ b/experiments_segmentation/run_segm_slic_classif_graphcut.py @@ -270,7 +270,7 @@ def load_dump_data(path_dump_data): logging.info('loading dumped data "%s"', path_dump_data) # with open(os.path.join(path_out, NAME_DUMP_TRAIN_DATA), 'r') as f: # dict_data = pickle.load(f) - npz_file = np.load(path_dump_data) + npz_file = np.load(path_dump_data, allow_pickle=True) dict_imgs = dict(npz_file['dict_images'].tolist()) dict_annot = dict(npz_file['dict_annot'].tolist()) dict_slics = dict(npz_file['dict_slics'].tolist()) diff --git a/imsegm/__init__.py b/imsegm/__init__.py index b409d64e..7d8d6709 100755 --- a/imsegm/__init__.py +++ b/imsegm/__init__.py @@ -11,7 +11,7 @@ import traceback traceback.print_exc() -__version__ = '0.1.7' +__version__ = '0.1.8' __author__ = 'Jiri Borovec' __author_email__ = 'jiri.borovec@fel.cvut.cz' __license__ = 'BSD 3-clause' diff --git a/imsegm/annotation.py b/imsegm/annotation.py index 97cf5f05..d15fb425 100755 --- a/imsegm/annotation.py +++ b/imsegm/annotation.py @@ -15,7 +15,7 @@ from scipy import interpolate # sys.path += [os.path.abspath('.'), os.path.abspath('..')] # Add path to root -from .utilities.data_io import io_imread +from imsegm.utilities.data_io import io_imread #: names of annotated columns COLUMNS_POSITION = ('ant_x', 'ant_y', 'post_x', 'post_y', 'lat_x', 'lat_y') diff --git a/imsegm/classification.py b/imsegm/classification.py index d83ca7ce..8aa890b6 100755 --- a/imsegm/classification.py +++ b/imsegm/classification.py @@ -31,8 +31,8 @@ except Exception: from sklearn.model_selection import GridSearchCV, RandomizedSearchCV -from .labeling import relabel_max_overlap_unique -from .utilities.experiments import WrapExecuteSequence, nb_workers +from imsegm.labeling import relabel_max_overlap_unique +from imsegm.utilities.experiments import WrapExecuteSequence, nb_workers # NAME_FILE_RESULTS = 'results.csv' #: name template forexporting trained classifier (adding classifier name and version) diff --git a/imsegm/ellipse_fitting.py b/imsegm/ellipse_fitting.py index 46d1cfb0..afbbe556 100755 --- a/imsegm/ellipse_fitting.py +++ b/imsegm/ellipse_fitting.py @@ -10,10 +10,10 @@ from skimage.measure import fit as sk_fit # from skimage.measure.fit import EllipseModel # fix in future skimage>0.13.0 -from .utilities.drawing import ellipse -from .descriptors import ( +from imsegm.utilities.drawing import ellipse +from imsegm.descriptors import ( reduce_close_points, compute_ray_features_segm_2d, reconstruct_ray_features_2d) -from .superpixels import ( +from imsegm.superpixels import ( segment_slic_img2d, superpixel_centers, make_graph_segm_connect_grid2d_conn4) # INIT_MASK_BORDER = 50. diff --git a/imsegm/graph_cuts.py b/imsegm/graph_cuts.py index b15f8c86..aaa15553 100755 --- a/imsegm/graph_cuts.py +++ b/imsegm/graph_cuts.py @@ -7,16 +7,20 @@ import logging import numpy as np -from gco import cut_general_graph +try: + from gco import cut_general_graph +except Exception: + print('WARNING: Missing Grah-Cut (GCO) library,' + ' please install it from https://github.com/Borda/pyGCO.') from skimage import filters from sklearn import metrics, preprocessing from sklearn import pipeline, cluster, mixture, decomposition -from .utilities.drawing import ( +from imsegm.utilities.drawing import ( draw_graphcut_unary_cost_segments, draw_graphcut_weighted_edges, draw_color_labeling) -from .superpixels import ( +from imsegm.superpixels import ( make_graph_segm_connect_grid2d_conn4, make_graph_segm_connect_grid3d_conn6, superpixel_centers) -from .descriptors import compute_selected_features_img2d +from imsegm.descriptors import compute_selected_features_img2d #: define munber of iteration in Grap-Cut optimization DEFAULT_GC_ITERATIONS = 25 diff --git a/imsegm/labeling.py b/imsegm/labeling.py index 0281444d..e215e433 100755 --- a/imsegm/labeling.py +++ b/imsegm/labeling.py @@ -10,7 +10,7 @@ from scipy import ndimage import skimage.segmentation as sk_segm -from .utilities.data_io import get_image2d_boundary_color +from imsegm.utilities.data_io import get_image2d_boundary_color def neighbour_connect4(seg, label, pos): diff --git a/imsegm/pipelines.py b/imsegm/pipelines.py index 5396853d..5383e390 100755 --- a/imsegm/pipelines.py +++ b/imsegm/pipelines.py @@ -11,14 +11,14 @@ import skimage.color as sk_color # from sklearn import mixture -from .utilities.experiments import WrapExecuteSequence, nb_workers -from .graph_cuts import segment_graph_cut_general, estim_class_model -from .superpixels import segment_slic_img2d, segment_slic_img3d_gray -from .descriptors import ( +from imsegm.utilities.experiments import WrapExecuteSequence, nb_workers +from imsegm.graph_cuts import segment_graph_cut_general, estim_class_model +from imsegm.superpixels import segment_slic_img2d, segment_slic_img3d_gray +from imsegm.descriptors import ( FEATURES_SET_COLOR, norm_features, compute_selected_features_img2d, compute_selected_features_gray3d) -from .labeling import histogram_regions_labels_norm -from .classification import ( +from imsegm.labeling import histogram_regions_labels_norm +from imsegm.classification import ( DEFAULT_CLASSIF_NAME, DEFAULT_CLUSTERING, convert_set_features_labels_2_dataset, CrossValidateGroups, create_classif_search_train_export) diff --git a/imsegm/region_growing.py b/imsegm/region_growing.py index 76d189bb..f26c208d 100755 --- a/imsegm/region_growing.py +++ b/imsegm/region_growing.py @@ -12,13 +12,17 @@ from scipy import stats, ndimage, interpolate from sklearn import cluster, mixture from skimage import morphology -from gco import cut_general_graph, cut_grid_graph - -from .graph_cuts import MAX_PAIRWISE_COST, get_vertexes_edges, compute_spatial_dist -from .labeling import histogram_regions_labels_norm -from .descriptors import ( +try: + from gco import cut_general_graph, cut_grid_graph +except Exception: + print('WARNING: Missing Grah-Cut (GCO) library,' + ' please install it from https://github.com/Borda/pyGCO.') + +from imsegm.graph_cuts import MAX_PAIRWISE_COST, get_vertexes_edges, compute_spatial_dist +from imsegm.labeling import histogram_regions_labels_norm +from imsegm.descriptors import ( compute_ray_features_segm_2d, interpolate_ray_dist, shift_ray_features) -from .superpixels import ( +from imsegm.superpixels import ( superpixel_centers, get_neighboring_segments, make_graph_segm_connect_grid2d_conn4) #: all infinty values in Grah-Cut terms replace by this value @@ -364,10 +368,11 @@ def transform_rays_model_cdf_mixture(list_rays, coef_components=1): >>> list_rays = [[9, 4, 9], [4, 9, 7], [9, 7, 11], [10, 8, 10], ... [9, 11, 8], [4, 8, 5], [8, 10, 6], [9, 7, 11]] >>> mm, cdist = transform_rays_model_cdf_mixture(list_rays) - >>> np.round(cdist, 1).tolist() # doctest: +NORMALIZE_WHITESPACE - [[1.0, 1.0, 1.0, 1.0, 1.0, 0.9, 0.8, 0.8, 0.6, 0.2, 0.0], - [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.9, 0.8, 0.5, 0.2, 0.0], - [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.9, 0.7, 0.5, 0.2, 0.0]] + >>> # the rounding variate a bit according GMM estimated model + >>> np.round(np.array(cdist) * 4) / 4. # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS + array([[ 1. , 1. , 1. , 1. , 1. , 1. , 0.75, 0.75, 0.5 , 0.25, 0. ], + [ 1. , 1. , 1. , 1. , 1. , 1. , 1. , 0.75, 0.5 , 0.25, 0. ], + [ 1. , 1. , 1. , 1. , 1. , 1. , ..., 0.75, 0.5 , 0.25, 0. ]]) """ rays = np.array(list_rays) ms = cluster.MeanShift() @@ -481,7 +486,7 @@ def transform_rays_model_cdf_spectral(list_rays, nb_components=5): >>> np.round(cdist, 1).tolist() # doctest: +NORMALIZE_WHITESPACE [[1.0, 1.0, 1.0, 1.0, 1.0, 0.9, 0.8, 0.6, 0.5, 0.2, 0.0], [1.0, 1.0, 1.0, 1.0, 1.0, 0.9, 0.9, 0.7, 0.5, 0.2, 0.0], - [1.0, 1.0, 1.0, 1.0, 1.0, 0.9, 0.8, 0.7, 0.5, 0.3, 0.0]] + [1.0, 1.0, 1.0, 1.0, 1.0, 0.9, 0.8, 0.7, 0.5, 0.3, 0.0]] """ rays = np.array(list_rays) sc = cluster.SpectralClustering(nb_components) diff --git a/imsegm/utilities/data_io.py b/imsegm/utilities/data_io.py index 10a231f7..74d19985 100644 --- a/imsegm/utilities/data_io.py +++ b/imsegm/utilities/data_io.py @@ -3,7 +3,6 @@ Copyright (C) 2015-2018 Jiri Borovec """ -from __future__ import absolute_import import os import re @@ -20,7 +19,7 @@ from skimage import exposure, io, color, measure import nibabel -from . import read_zvi +from imsegm.utilities.read_zvi import load_image as load_zvi #: position columns COLUMNS_COORDS = ['X', 'Y'] @@ -733,7 +732,7 @@ def load_zvi_volume_double_band_split(path_img): (2, 488, 648) """ assert os.path.isfile(path_img), 'missing: %s' % path_img - img = read_zvi.load_image(path_img) + img = load_zvi(path_img) nb_half = img.shape[0] / 2 img_b1 = img[:int(nb_half)] img_b2 = img[int(nb_half):] @@ -1058,14 +1057,21 @@ def add_padding(img_size, padding, min_row, min_col, max_row, max_col): return min_row, min_col, max_row, max_col -def cut_object(img, mask, padding, use_mask=False, bg_color=None): - """ cut an object fro image according binary object segmentation +# prepare a simple mask with one horizontal segment +prop = measure.regionprops(np.array([[0] * 20, [1] * 20, [0] * 20], dtype=int))[0] +#: according to skimage version the major axis are swapped +PROP_ROTATION_OFFSET = prop.orientation - :param ndarray img: - :param ndarray mask: + +def cut_object(img, mask, padding, use_mask=False, bg_color=None, allow_rotate=True): + """ cut an object from image according binary object segmentation + + :param ndarray img: inout image + :param ndarray mask: segmentation :param int padding: set padding around segmented object - :param use_mask: fill BG values also outside the mask + :param bool use_mask: fill BG values also outside the mask :param bg_color: set as default values outside bounding box + :param bool allow_rotate: allowing rotate object to get minimal bbox :return: >>> img = np.ones((10, 20), dtype=int) @@ -1079,7 +1085,7 @@ def cut_object(img, mask, padding, use_mask=False, bg_color=None): [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1], [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]) - >>> cut_object(img, mask, 2, use_mask=True) + >>> cut_object(img, mask, 2, use_mask=True, allow_rotate=False) array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1], @@ -1096,15 +1102,18 @@ def cut_object(img, mask, padding, use_mask=False, bg_color=None): if not bg_color: bg_color = get_image2d_boundary_color(img) - rotate = np.rad2deg(prop.orientation) - shift = prop.centroid - (np.array(mask.shape) / 2.) - shift = np.append(shift, np.zeros(img.ndim - mask.ndim)) + if allow_rotate: + rotate = np.rad2deg(prop.orientation - PROP_ROTATION_OFFSET) + shift = prop.centroid - (np.array(mask.shape) / 2.) + shift = np.append(shift, np.zeros(img.ndim - mask.ndim)) + + mask = ndimage.interpolation.shift(mask, -shift[:mask.ndim], order=0) + mask = ndimage.rotate(mask, -rotate, order=0, mode='constant', cval=np.nan) - mask = ndimage.interpolation.shift(mask, -shift[:mask.ndim], order=0) - mask = ndimage.rotate(mask, -rotate, order=0, mode='constant', cval=np.nan) + img = ndimage.interpolation.shift(img, -shift[:img.ndim], order=0) + img = ndimage.rotate(img, -rotate, order=0, mode='constant', cval=np.nan) - img_cut = ndimage.interpolation.shift(img, -shift[:img.ndim], order=0) - img_cut = ndimage.rotate(img_cut, -rotate, order=0, mode='constant', cval=np.nan) + img_cut = img.copy() img_cut[np.isnan(mask), ...] = bg_color mask[np.isnan(mask)] = bg_mask diff --git a/imsegm/utilities/data_samples.py b/imsegm/utilities/data_samples.py index e5954106..1b829d1d 100644 --- a/imsegm/utilities/data_samples.py +++ b/imsegm/utilities/data_samples.py @@ -9,7 +9,6 @@ Copyright (C) 2015-2018 Jiri Borovec """ -from __future__ import absolute_import import os import logging @@ -17,7 +16,7 @@ # from PIL import Image import numpy as np -from .data_io import update_path, io_imread +from imsegm.utilities.data_io import update_path, io_imread #: image size for small 2D sample image SAMPLE_SEG_SIZE_2D_SMALL = (20, 10) diff --git a/requirements-py27.txt b/requirements-py27.txt new file mode 100644 index 00000000..8d51c5d2 --- /dev/null +++ b/requirements-py27.txt @@ -0,0 +1,16 @@ +six >= 1.7.3 +Cython >= 0.23 +numpy >= 1.9, < 1.16.0 # version 1.16 breaks skimage 0.14 +scipy >= 0.15.1, < 1.3 +pandas >= 0.14.1, < 0.24 +pillow >= 2.1.0 +matplotlib >= 2.0.2, < 3.0.0 +scikit-learn >= 0.18.1, < 0.21 +scikit-image >= 0.13.0, < 0.15 +tqdm >= 4.7.4, <= 4.30 # higher fails ascii for py2 +olefile == 0.44 # new version - ImportError: No module named OleFileIO_PL +nibabel >= 2.1.0 +planar >= 0.4 +# networkx <= 2.2 +https://github.com/Borda/pyGCO/archive/master.zip#egg=gco-wrapper>=3.0.3 +pyyaml \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index cd62e1fc..982ecbc8 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,16 +1,16 @@ -numpy >= 1.8.2, < 1.16.0 # version 1.16 breaks skimage 0.14 -scipy >= 0.15.1, < 1.3 # new version does not support py2 -pandas >= 0.14.1, < 0.24 # new version does not support py2 six >= 1.7.3 +Cython >= 0.28 # 0.27 fails with python 3.7 +numpy >= 1.13.3 # version 1.16 breaks skimage 0.14 +scipy >= 1.0 +pandas >= 0.19 pillow >= 2.1.0 -Cython >= 0.23 -matplotlib >= 2.0.2, < 3.0.0 # new version does not support py2 -scikit-learn >= 0.18.1, < 0.21 # new version does not support py2 -scikit-image >= 0.13.0, < 0.15 # new version does not support py2 -tqdm >= 4.7.4, <= 4.30 # higher fails ascii for py2 +matplotlib >= 2.0.2 +scikit-learn >= 0.18.1 +scikit-image >= 0.13.0 +tqdm >= 4.7.4 olefile == 0.44 # new version - ImportError: No module named OleFileIO_PL nibabel >= 2.1.0 planar >= 0.4 -networkx <= 2.2 # new version does not support py2 +# networkx https://github.com/Borda/pyGCO/archive/master.zip#egg=gco-wrapper>=3.0.3 -pyyaml \ No newline at end of file +pyyaml >= 5.1 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 0c61b02b..fb780da5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,4 +1,14 @@ [metadata] description-file = README.md license-file = LICENSE -requirements-file = requirements.txt \ No newline at end of file +requirements-file = requirements.txt + +#[unittest] +#plugins = nose2.plugins.doctests + +[flake8] +# http://flake8.pycqa.org/en/latest/user/configuration.html +ignore = E402,E731 +max-line-length = 100 +# exclude = tests/* +# max-complexity = 10 \ No newline at end of file diff --git a/setup.py b/setup.py index baae757b..cb337b5a 100644 --- a/setup.py +++ b/setup.py @@ -54,12 +54,14 @@ def finalize_options(self): def _parse_requirements(file_path): with open(file_path) as fp: reqs = [r.rstrip() for r in fp.readlines() if not r.startswith('#')] + # drop all proprietary packages missing from PiPy + reqs = filter(lambda r: not r.startswith('http'), reqs) # parse egg names if there are paths reqs = [r[r.index(TEMP_EGG) + len(TEMP_EGG):] if TEMP_EGG in r else r for r in reqs] return reqs -setup_reqs = ['Cython', 'numpy<1.17'] # numpy v1.17 drops support for py2 +setup_reqs = ['Cython', 'numpy'] # numpy v1.17 drops support for py2 install_reqs = _parse_requirements(os.path.join(HERE, 'requirements.txt')) diff --git a/tests/requirements.txt b/tests/requirements.txt index ee57b07b..4acf0d3d 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,8 +1,9 @@ -nose>=1.3.7 +# nose>=1.3.7 coverage codecov pytest>=3.0.5 pytest-cov +pytest-flake8 codacy-coverage check-manifest flake8 \ No newline at end of file diff --git a/tests/test_region-growing.py b/tests/test_region-growing.py index c3b4f8f5..6df4f685 100644 --- a/tests/test_region-growing.py +++ b/tests/test_region-growing.py @@ -127,7 +127,7 @@ def test_region_growing_greedy(self, name='insitu7545'): self.test_shape_modeling() # file_model = pickle.load(open(PATH_PKL_MODEL, 'r')) - npz_file = np.load(PATH_PKL_MODEL) + npz_file = np.load(PATH_PKL_MODEL, allow_pickle=True) file_model = dict(npz_file[npz_file.files[0]].tolist()) logging.info('loaded model: %r', file_model.keys()) list_mean_cdf = file_model['cdfs'] @@ -167,7 +167,7 @@ def test_region_growing_graphcut(self, name='insitu7545'): self.test_shape_modeling() # file_model = pickle.load(open(PATH_PKL_MODEL, 'r')) - npz_file = np.load(PATH_PKL_MODEL) + npz_file = np.load(PATH_PKL_MODEL, allow_pickle=True) file_model = dict(npz_file[npz_file.files[0]].tolist()) logging.info('loaded model: %r', file_model.keys()) list_mean_cdf = file_model['cdfs']