From f6ddf59d5f746ae6f40f11a9662be213df750a8e Mon Sep 17 00:00:00 2001 From: Luis Pedro Coelho Date: Sat, 27 Sep 2014 12:46:47 +0200 Subject: [PATCH] BUG Correctly handle float16 & float128 types Float128 is now correctly handled, while a meaningful error message is printed for float16. Closes #47 --- mahotas/numpypp/dispatch.hpp | 19 +++++++++-- mahotas/numpypp/numpy.hpp | 3 +- mahotas/tests/test_watershed.py | 57 +++++++++++++++++++-------------- 3 files changed, 51 insertions(+), 28 deletions(-) diff --git a/mahotas/numpypp/dispatch.hpp b/mahotas/numpypp/dispatch.hpp index b9a77534..9dc5c511 100644 --- a/mahotas/numpypp/dispatch.hpp +++ b/mahotas/numpypp/dispatch.hpp @@ -1,3 +1,7 @@ +/* Copyright 2010-2014 (C) + * Luis Pedro Coelho + * License: MIT + */ typedef unsigned char uchar; typedef unsigned short ushort; #define HANDLE_INTEGER_TYPES() \ @@ -13,16 +17,24 @@ typedef unsigned short ushort; #define HANDLE_FLOAT_TYPES() \ case NPY_FLOAT: HANDLE(float); break; \ - case NPY_DOUBLE: HANDLE(double); break; + case NPY_DOUBLE: HANDLE(double); break; \ + case NPY_FLOAT128: HANDLE(npy_float128); break; #define HANDLE_TYPES() \ HANDLE_INTEGER_TYPES() \ HANDLE_FLOAT_TYPES() +#define HANDLE_FLOAT16() \ + case NPY_FLOAT16: \ + PyErr_SetString(PyExc_TypeError, "Mahotas does not support float16. " \ + "Please convert your data before calling mahotas functions."); \ + return NULL; + #define SAFE_SWITCH_ON_TYPES_OF(array) \ try { \ switch(PyArray_TYPE(array)) { \ HANDLE_TYPES();\ + HANDLE_FLOAT16(); \ default: \ PyErr_SetString(PyExc_RuntimeError, "Dispatch on types failed!"); \ return NULL; \ @@ -45,9 +57,10 @@ typedef unsigned short ushort; try { \ switch(PyArray_TYPE(array)) { \ HANDLE_FLOAT_TYPES();\ + HANDLE_FLOAT16(); \ default: \ - PyErr_SetString(PyExc_RuntimeError, "Dispatch on types failed!"); \ - return NULL; \ + PyErr_SetString(PyExc_RuntimeError, "Dispatch on types failed!"); \ + return NULL; \ } \ } \ CATCH_PYTHON_EXCEPTIONS diff --git a/mahotas/numpypp/numpy.hpp b/mahotas/numpypp/numpy.hpp index a272b498..213a6106 100644 --- a/mahotas/numpypp/numpy.hpp +++ b/mahotas/numpypp/numpy.hpp @@ -1,6 +1,6 @@ #ifndef MAHOTAS_NUMPYPP_NUMPY_HPP_INCLUDE_GUARD_LPC_ #define MAHOTAS_NUMPYPP_NUMPY_HPP_INCLUDE_GUARD_LPC_ -/* Copyright 2010-2012 (C) +/* Copyright 2010-2014 (C) * Luis Pedro Coelho * License: MIT */ @@ -41,6 +41,7 @@ DECLARE_DTYPE_CODE(unsigned long, NPY_ULONG) DECLARE_DTYPE_CODE(long long, NPY_LONGLONG) DECLARE_DTYPE_CODE(unsigned long long, NPY_ULONGLONG) DECLARE_DTYPE_CODE(double, NPY_DOUBLE) +DECLARE_DTYPE_CODE(npy_float128, NPY_FLOAT128) DECLARE_DTYPE_CODE(std::complex, NPY_CFLOAT) DECLARE_DTYPE_CODE(std::complex, NPY_CDOUBLE) DECLARE_DTYPE_CODE(unsigned int, NPY_UINT) diff --git a/mahotas/tests/test_watershed.py b/mahotas/tests/test_watershed.py index eded5c33..d04e8286 100644 --- a/mahotas/tests/test_watershed.py +++ b/mahotas/tests/test_watershed.py @@ -3,30 +3,30 @@ import mahotas as mh import sys from nose.tools import raises +S = np.array([ + [0,0,0,0], + [0,1,2,1], + [1,1,1,1], + [0,0,1,0], + [1,1,1,1], + [1,2,2,1], + [1,1,2,2] + ]) +M = np.array([ + [0,0,0,0], + [0,0,1,0], + [0,0,0,0], + [0,0,0,0], + [0,0,0,0], + [0,2,0,0], + [0,0,0,0], + ]) def test_watershed(): - S = np.array([ - [0,0,0,0], - [0,1,2,1], - [1,1,1,1], - [0,0,1,0], - [1,1,1,1], - [1,2,2,1], - [1,1,2,2] - ]) - M = np.array([ - [0,0,0,0], - [0,0,1,0], - [0,0,0,0], - [0,0,0,0], - [0,0,0,0], - [0,2,0,0], - [0,0,0,0], - ]) - def cast_test(M,S,dtype): - M = M.astype(dtype) - S = S.astype(dtype) - W = mahotas.cwatershed(2-S,M) + def cast_test(dtype): + St = S.astype(dtype) + Mt = M.astype(int) + W = mahotas.cwatershed(2-St,Mt) assert sys.getrefcount(W) == 2 assert np.all(W == np.array([[1, 1, 1, 1], [1, 1, 1, 1], @@ -35,8 +35,17 @@ def cast_test(M,S,dtype): [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2]])) - for d in [np.uint8, np.int8, np.uint16, np.int16, np.int32, np.uint32,int]: - yield cast_test, M, S, d + for d in [np.uint8, np.int8, np.uint16, np.int16, np.int32, np.uint32,int, + np.float32, np.float64, np.float128, float]: + yield cast_test, d + + +@raises(TypeError) +def test_float16(): + dtype = np.float16 + St = S.astype(dtype) + Mt = M.astype(int) + mh.cwatershed(2-St,Mt) def test_watershed2():