Skip to content

Commit

Permalink
Merge branch 'release-0.46'
Browse files Browse the repository at this point in the history
  • Loading branch information
mcvaneede committed Jul 15, 2016
2 parents 956ea27 + 0b221f3 commit 43760de
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 15 deletions.
8 changes: 8 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
New in version 0.46
===================
* when using volumeFromDescription and volumeFromData, these numpy types are now properly supported:
numpy.int8, numpy.int16, numpy.int32, numpy.float32, numpy.float64, numpy.uint8, numpy.uint16, numpy.uint32
numpy.dtype("int8"), numpy.dtype("int16"), numpy.dtype("int32"), numpy.dtype("float32"), numpy.dtype("float64"),
numpy.dtype("uint8"), numpy.dtype("uint16"), numpy.dtype("uint32")
* changed the "from numpy import *" to "import numpy as numpy" to avoid possible name space clashes

New in version 0.45
===================
* when MINC volumes are read, their volume type on disk is determined (byte, unsigned short, float etc.) and preserved. The data type of the MINC representation in Python (numpy) is double by default to maintain presicion. You do have full control over what you want the volume type on disk to be for your MINC volumes in Python.
Expand Down
1 change: 0 additions & 1 deletion pyminc/volumes/libpyminc2.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from ctypes.util import find_library
import _ctypes
import locale
from numpy import *
import sys

# load the library
Expand Down
81 changes: 68 additions & 13 deletions pyminc/volumes/volumes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import datetime as datetime
from functools import reduce
import subprocess
import numpy as numpy

class mincException(Exception): pass
class NoDataException(Exception): pass
Expand All @@ -28,7 +29,7 @@ def __init__(self, filename=None, dtype=None, readonly=True, labels=False):
self.sizes = int_sizes() # holds dimension sizes info
self.dataLoadable = False # we know enough about the file on disk to load data
self.dataLoaded = False # data sits inside the .data attribute
self.dtype = dtype # data type for array representation (in Python)
self.dtype = dtype # numpy data type for array representation (in Python) can either be a string (str) or of type numpy.dtype
self.volumeType = None # data type on file, will be determined by openFile()
self.filename = filename # the filename associated with this volume
self.readonly = readonly # flag indicating that volume is for reading only
Expand All @@ -41,7 +42,7 @@ def __init__(self, filename=None, dtype=None, readonly=True, labels=False):
self._y_direction_cosines = None
self._z_direction_cosines = None
self._data_written_to_file = False

def getDtype(self, data):
"""get the mincSizes datatype based on a numpy array"""
dtype = None
Expand All @@ -53,6 +54,48 @@ def getDtype(self, data):
break
return dtype

def numpy_type_to_string(self, dtype_in_numpy_form):
# if the dtype is not found, return "unknown"
return {
numpy.int8 : "byte",
numpy.int16 : "short",
numpy.int32 : "int",
numpy.float32 : "float",
numpy.float64 : "double",
numpy.uint8 : "ubyte",
numpy.uint16 : "ushort",
numpy.uint32 : "uint",
"int8" : "byte",
"int16" : "short",
"int32" : "int",
"float32" : "float",
"float64" : "double",
"uint8" : "ubyte",
"uint16" : "ushort",
"uint32" : "uint",
numpy.dtype("int8") : "byte",
numpy.dtype("int16") : "short",
numpy.dtype("int32") : "int",
numpy.dtype("float32") : "float",
numpy.dtype("float64") : "double",
numpy.dtype("uint8") : "ubyte",
numpy.dtype("uint16") : "ushort",
numpy.dtype("uint32") : "uint",
}.get(dtype_in_numpy_form, "unknown")

def get_string_form_of_numpy_dtype(self, dtype_in_numpy_form):
"""convert the variable of type numpy.dtype in the string (str) equivalent"""
if type(dtype_in_numpy_form) == str:
if self.debug:
print("dtype provided to get_string_form_of_numpy_dtype was already in string format: ", dtype_in_numpy_form)
# it's already fine:
return dtype_in_numpy_form
string_form = self.numpy_type_to_string(dtype_in_numpy_form)
if string_form == "unknown":
sys.stderr.write("Could not convert numpy.dtype: " + str(dtype_in_numpy_form) + " to the equivalent minc format...")
raise NoDataException
return string_form

def getdata(self):
"""called when data attribute requested"""
#print("getting data")
Expand Down Expand Up @@ -90,7 +133,7 @@ def loadData(self):
self.dataLoaded = True
elif self.ndims > 0:
length = reduce(operator.mul, self.sizes[0:self.ndims])
self._data = zeros(length, order=self.order, dtype=self.dtype)
self._data = numpy.zeros(length, order=self.order, dtype=self.dtype)
self._data.shape = self.sizes[0:self.ndims]
else:
raise NoDataException
Expand All @@ -110,12 +153,17 @@ def getHyperslab(self, start, count, dtype=None):
if self.debug:
print("We are loading the data from this file using dtype: ", dtype_to_get)

start = array(start[:self.ndims])
count = array(count[:self.ndims])
# dtype_to_get can be provided either as a string, or as a variable of type
# numpy.dtype. In the latter case, we should convert it here to the string form
if type(dtype_to_get) == numpy.dtype:
dtype_to_get = self.get_string_form_of_numpy_dtype(dtype_to_get)

start = numpy.array(start[:self.ndims])
count = numpy.array(count[:self.ndims])
size = reduce(operator.mul, count)
if self.debug:
print(start[:], count[:], size)
a = HyperSlab(zeros(count, dtype=mincSizes[dtype_to_get]["numpy"], order=self.order),
a = HyperSlab(numpy.zeros(count, dtype=mincSizes[dtype_to_get]["numpy"], order=self.order),
start=start, count=count, separations=self.separations)

if self.dataLoaded:
Expand Down Expand Up @@ -194,16 +242,23 @@ def writeFile(self):
if not self.dataLoadable: # if file doesn't yet exist on disk
self.createVolumeImage()
if self.dataLoaded: # only write if data is in memory
# find the datatype map index
dtype = self.dtype
if not dtype:
# find the datatype map index. If self.dtype is of type numpy.dtype
# (not self.dtype) will return True...
if (not type(self.dtype == numpy.dtype) and
self.dtype == None) :
sys.stderr.write("dtype unknown in writeFile...")
raise NoDataTypeException
self.setVolumeRanges(self._data)

# in the next libminc call we use the string form of the numpy representation...
if type(self.dtype) == numpy.dtype:
self.dtype = self.get_string_form_of_numpy_dtype(self.dtype)


r = libminc.miset_real_value_hyperslab(
self.volPointer, mincSizes[dtype]["minc"],
self.volPointer, mincSizes[self.dtype]["minc"],
misize_t_sizes(), misize_t_sizes(*self.sizes[:]),
self._data.ctypes.data_as(POINTER(mincSizes[dtype]["ctype"])))
self._data.ctypes.data_as(POINTER(mincSizes[self.dtype]["ctype"])))
testMincReturn(r)
self._data_written_to_file = True

Expand Down Expand Up @@ -668,7 +723,7 @@ def convertVoxelToWorld(self, voxel):
c_voxel[:self.ndims] = voxel
status = libminc.miconvert_voxel_to_world(self.volPointer, c_voxel, c_world)
testMincReturn(status)
return array(c_world[:])
return numpy.array(c_world[:])


#Jason's version of convertVoxelToWorld:
Expand All @@ -692,7 +747,7 @@ def convertWorldToVoxel(self, world):
c_world[:] = world
status = libminc.miconvert_world_to_voxel(self.volPointer, c_world, c_voxel)
testMincReturn(status)
return array(c_voxel[:self.ndims])
return numpy.array(c_voxel[:self.ndims])



Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from setuptools import setup, find_packages

setup(name='pyminc',
version = '0.45',
version = '0.46',
description = "Python interface to libminc",
url = "https://github.com/Mouse-Imaging-Centre/pyminc",
author = "Jason Lerch",
Expand Down

0 comments on commit 43760de

Please sign in to comment.