diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..9c76c8b --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,22 @@ +on: [push, pull_request] + +defaults: + run: + shell: bash + +jobs: + + test: + runs-on: ubuntu-18.04 + strategy: + matrix: + python-version: [3.6, 3.7, 3.8, 3.9] + fail-fast: false + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - run: pip install -U pip -r requirements.txt + - run: bash make.sh + - run: python malis/test_malis.py diff --git a/make.sh b/make.sh index 2f3389e..a99e365 100755 --- a/make.sh +++ b/make.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash +set -ex cd malis python setup.py build_ext --inplace printf "BUILD COMPLETE\n" -cd .. \ No newline at end of file +cd .. diff --git a/malis/test_malis.py b/malis/test_malis.py index 27453fc..24a17ad 100644 --- a/malis/test_malis.py +++ b/malis/test_malis.py @@ -5,16 +5,16 @@ import malis as m -print "Can we make the `nhood' for an isotropic 3d dataset" -print "corresponding to a 6-connected neighborhood?" +print("Can we make the `nhood' for an isotropic 3d dataset") +print("corresponding to a 6-connected neighborhood?") nhood = m.mknhood3d(1) -print nhood +print(nhood -print "Can we make the `nhood' for an anisotropic 3d dataset" -print "corresponding to a 4-connected neighborhood in-plane" -print "and 26-connected neighborhood in the previous z-plane?" +print("Can we make the `nhood' for an anisotropic 3d dataset") +print("corresponding to a 4-connected neighborhood in-plane") +print("and 26-connected neighborhood in the previous z-plane?") nhood = m.mknhood3d_aniso(1,1.8) -print nhood +print(nhood) segTrue = np.array([0, 1, 1, 1, 2, 2, 0, 5, 5, 5, 5],dtype=np.uint64); node1 = np.arange(segTrue.shape[0]-1,dtype=np.uint64) @@ -22,27 +22,27 @@ nVert = segTrue.shape[0] edgeWeight = np.array([0, 1, 2, 0, 2, 0, 0, 1, 2, 2.5],dtype=np.float32); edgeWeight = edgeWeight/edgeWeight.max() -print segTrue -print edgeWeight +print(segTrue) +print(edgeWeight) nPairPos = m.malis_loss_weights(segTrue, node1, node2, edgeWeight, 1) nPairNeg = m.malis_loss_weights(segTrue, node1, node2, edgeWeight, 0) -print np.vstack((nPairPos,nPairNeg)) -# print nPairNeg +print(np.vstack((nPairPos,nPairNeg)) +# print(nPairNeg idxkeep = (edgeWeight > 0).astype(np.int32) cc = m.connected_components(nVert,node1,node2,idxkeep) -print cc +print(cc) # node1, node2 = m.nodelist_like((2,3,4),-np.eye(3)) -# print node1 -# print node2 +# print(node1) +# print(node2) datadir = '/groups/turaga/turagalab/greentea/project_data/dataset_06/fibsem_medulla_7col/tstvol-520-1-h5/' -print "[" +str(datetime.datetime.now())+"]" + "Reading test volume from " + datadir +print( "[" +str(datetime.datetime.now())+"]" + "Reading test volume from " + datadir) # hdf5_raw_file = datadir + 'img_normalized.h5' hdf5_gt_file = datadir + 'groundtruth_seg.h5' # hdf5_aff_file = datadir + 'groundtruth_aff.h5' @@ -56,28 +56,28 @@ # hdf5_aff = h5py.File(hdf5_aff_file, 'r') seg = np.asarray(h5seg['main']).astype(np.int32) -print "[" +str(datetime.datetime.now())+"]" + "Making affinity graph..." +print("[" +str(datetime.datetime.now())+"]" + "Making affinity graph...") aff = m.seg_to_affgraph(seg,nhood) -print "[" +str(datetime.datetime.now())+"]" + "Affinity shape:" + str(aff.shape) -print "[" +str(datetime.datetime.now())+"]" + "Computing connected components..." +print("[" +str(datetime.datetime.now())+"]" + "Affinity shape:" + str(aff.shape)) +print("[" +str(datetime.datetime.now())+"]" + "Computing connected components...") cc,ccSizes = m.connected_components_affgraph(aff,nhood) -print "[" +str(datetime.datetime.now())+"]" + "Making affinity graph again..." +print("[" +str(datetime.datetime.now())+"]" + "Making affinity graph again...") aff2 = m.seg_to_affgraph(cc,nhood) -print "[" +str(datetime.datetime.now())+"]" + "Computing connected components..." +print("[" +str(datetime.datetime.now())+"]" + "Computing connected components...") cc2,ccSizes2 = m.connected_components_affgraph(aff2,nhood) -print "[" +str(datetime.datetime.now())+"]" + "Comparing 'seg' and 'cc':" +print("[" +str(datetime.datetime.now())+"]" + "Comparing 'seg' and 'cc':") # ri,fscore,prec,rec = m.rand_index(seg,cc) -# print "\tRand index: %f, fscore: %f, prec: %f, rec: %f" % (ri,fscore,prec,rec) +# print("\tRand index: %f, fscore: %f, prec: %f, rec: %f" % (ri,fscore,prec,rec)) V_rand,V_rand_split,V_rand_merge = m.compute_V_rand_N2(seg,cc) -print "[" +str(datetime.datetime.now())+"]" + "\tV_rand: %f, V_rand_split: %f, V_rand_merge: %f" % (V_rand,V_rand_split,V_rand_merge) +print("[" +str(datetime.datetime.now())+"]" + "\tV_rand: %f, V_rand_split: %f, V_rand_merge: %f" % (V_rand,V_rand_split,V_rand_merge)) -print "[" +str(datetime.datetime.now())+"]" + "Comparing 'cc' and 'cc2':" +print("[" +str(datetime.datetime.now())+"]" + "Comparing 'cc' and 'cc2':") # ri,fscore,prec,rec = m.rand_index(cc,cc2) -# print "\tRand index: %f, fscore: %f, prec: %f, rec: %f" % (ri,fscore,prec,rec) +# print("\tRand index: %f, fscore: %f, prec: %f, rec: %f" % (ri,fscore,prec,rec) V_rand,V_rand_split,V_rand_merge = m.compute_V_rand_N2(cc,cc2) -print "[" +str(datetime.datetime.now())+"]" + "\tV_rand: %f, V_rand_split: %f, V_rand_merge: %f" % (V_rand,V_rand_split,V_rand_merge) +print("[" +str(datetime.datetime.now())+"]" + "\tV_rand: %f, V_rand_split: %f, V_rand_merge: %f" % (V_rand,V_rand_split,V_rand_merge)) diff --git a/requirements.txt b/requirements.txt index 9d4cc7e..7e73aa5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,9 @@ # runtime Cython>=0.24 -numpy>=1.9 -scipy # unknown minimum version... +# https://github.com/TuragaLab/malis/issues/6 +numpy>=1.9,<1.12 +# https://github.com/TuragaLab/malis/issues/8 +scipy<1.3 # tests h5py diff --git a/setup.py b/setup.py index d65827c..844ee16 100644 --- a/setup.py +++ b/setup.py @@ -7,11 +7,11 @@ include_dirs = [ os.path.join(os.path.dirname(os.path.abspath(__file__)), "malis"), os.path.dirname(get_python_inc()), - get_python_inc() + get_python_inc(), ] library_dirs = [ os.path.join(os.path.dirname(os.path.abspath(__file__)), "malis"), - get_config_var("LIBDIR") + get_config_var("LIBDIR"), ] # Remove the "-Wstrict-prototypes" compiler option, which isn't valid for C++. @@ -19,33 +19,40 @@ if "CFLAGS" in cfg_vars: cfg_vars["CFLAGS"] = cfg_vars["CFLAGS"].replace("-Wstrict-prototypes", "") + class build_ext(_build_ext): def finalize_options(self): _build_ext.finalize_options(self) # Prevent numpy from thinking it is still in its setup process: __builtins__.__NUMPY_SETUP__ = False import numpy + self.include_dirs.append(numpy.get_include()) -setup(name='malis', - version='1.0', - description='MALIS segmentation loss function', - url='https://github.com/TuragaLab/malis', - author='Srinivas Turaga', - author_email='turagas@janelia.hhmi.org', - cmdclass=dict( - build_ext=build_ext - ), - license='MIT', - install_requires=['cython','numpy','h5py','scipy'], - setup_requires=['cython','numpy','scipy'], - packages=['malis'], - ext_modules = [Extension("malis.malis", - ["malis/malis.pyx", "malis/malis_cpp.cpp"], - include_dirs=include_dirs, - library_dirs=library_dirs, - language='c++', - # std= 'c++11', - extra_link_args=["-std=c++11"], - extra_compile_args=["-std=c++11", "-w"])], - zip_safe=False) + +setup( + name="malis", + version="1.0", + description="MALIS segmentation loss function", + url="https://github.com/TuragaLab/malis", + author="Srinivas Turaga", + author_email="turagas@janelia.hhmi.org", + cmdclass=dict(build_ext=build_ext), + license="MIT", + install_requires=["cython", "numpy", "h5py", "scipy"], + setup_requires=["cython", "numpy", "scipy"], + packages=["malis"], + ext_modules=[ + Extension( + "malis.malis", + ["malis/malis.pyx", "malis/malis_cpp.cpp"], + include_dirs=include_dirs, + library_dirs=library_dirs, + language="c++", + # std= 'c++11', + extra_link_args=["-std=c++11"], + extra_compile_args=["-std=c++11", "-w"], + ) + ], + zip_safe=False, +)