Created
November 24, 2012 22:46
-
-
Save will-moore/4141708 to your computer and use it in GitHub Desktop.
createImageFromNumpySeq in OMERO Python Blitz Gateway, updated to work in the non-default group (adding self.SERVICE_OPTS to all server calls)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def createImageFromNumpySeq (self, zctPlanes, imageName, sizeZ=1, sizeC=1, sizeT=1, description=None, dataset=None): | |
""" | |
Creates a new multi-dimensional image from the sequence of 2D numpy arrays in zctPlanes. | |
zctPlanes should be a generator of numpy 2D arrays of shape (sizeY, sizeX) ordered | |
to iterate through T first, then C then Z. | |
Example usage: | |
original = conn.getObject("Image", 1) | |
sizeZ = original.getSizeZ() | |
sizeC = original.getSizeC() | |
sizeT = original.getSizeT() | |
zctList = [] | |
for z in range(sizeZ): | |
for c in range(sizeC): | |
for t in range(sizeT): | |
zctList.append( (z,c,t) ) | |
def planeGen(): | |
planes = original.getPrimaryPixels().getPlanes(zctList) | |
for p in planes: | |
# perform some manipulation on each plane | |
yield p | |
createImageFromNumpySeq (planeGen(), imageName, sizeZ=sizeZ, sizeC=sizeC, sizeT=sizeT | |
@param session An OMERO service factory or equivalent with getQueryService() etc. | |
@param zctPlanes A generator of numpy 2D arrays, corresponding to Z-planes of new image. | |
@param imageName Name of new image | |
@param description Description for the new image | |
@param dataset If specified, put the image in this dataset. omero.model.Dataset object | |
@return The new OMERO image: omero.model.ImageI | |
""" | |
queryService = self.getQueryService() | |
pixelsService = self.getPixelsService() | |
rawPixelsStore = self.c.sf.createRawPixelsStore() # Make sure we don't get an existing rpStore | |
#renderingEngine = self.createRenderingEngine() | |
containerService = self.getContainerService() | |
updateService = self.getUpdateService() | |
def createImage(firstPlane): | |
""" Create our new Image once we have the first plane in hand """ | |
# need to map numpy pixel types to omero - don't handle: bool_, character, int_, int64, object_ | |
pTypes = {'int8':'int8', 'int16':'int16', 'uint16':'uint16', 'int32':'int32', 'float_':'float', 'float8':'float', | |
'float16':'float', 'float32':'float', 'float64':'double', 'complex_':'complex', 'complex64':'complex'} | |
dType = firstPlane.dtype.name | |
if dType not in pTypes: # try to look up any not named above | |
pType = dType | |
else: | |
pType = pTypes[dType] | |
pixelsType = queryService.findByQuery("from PixelsType as p where p.value='%s'" % pType, None) # omero::model::PixelsType | |
if pixelsType is None: | |
raise Exception("Cannot create an image in omero from numpy array with dtype: %s" % dType) | |
sizeY, sizeX = firstPlane.shape | |
channelList = range(1, sizeC+1) | |
iId = pixelsService.createImage(sizeX, sizeY, sizeZ, sizeT, channelList, pixelsType, imageName, description, self.SERVICE_OPTS) | |
imageId = iId.getValue() | |
return containerService.getImages("Image", [imageId], None, self.SERVICE_OPTS)[0] | |
def uploadPlane(plane, z, c, t): | |
byteSwappedPlane = plane.byteswap(); | |
convertedPlane = byteSwappedPlane.tostring(); | |
rawPixelsStore.setPlane(convertedPlane, z, c, t, self.SERVICE_OPTS) | |
image = None | |
channelsMinMax = [] | |
exc = None | |
try: | |
for theZ in range(sizeZ): | |
for theC in range(sizeC): | |
for theT in range(sizeT): | |
plane = zctPlanes.next() | |
if image == None: # use the first plane to create image. | |
image = createImage(plane) | |
print "new image group:", image.details.group.id.val | |
pixelsId = image.getPrimaryPixels().getId().getValue() | |
rawPixelsStore.setPixelsId(pixelsId, True, self.SERVICE_OPTS) | |
uploadPlane(plane, theZ, theC, theT) | |
# init or update min and max for this channel | |
minValue = plane.min() | |
maxValue = plane.max() | |
if len(channelsMinMax) < (theC +1): # first plane of each channel | |
channelsMinMax.append( [minValue, maxValue] ) | |
else: | |
channelsMinMax[theC][0] = min(channelsMinMax[theC][0], minValue) | |
channelsMinMax[theC][1] = max(channelsMinMax[theC][1], maxValue) | |
except Exception, e: | |
logger.error("Failed to setPlane() on rawPixelsStore while creating Image", exc_info=True) | |
exc = e | |
try: | |
rawPixelsStore.close(self.SERVICE_OPTS) | |
except Exception, e: | |
logger.error("Failed to close rawPixelsStore", exc_info=True) | |
if exc is None: | |
exc = e | |
if exc is not None: | |
raise exc | |
try: # simply completing the generator - to avoid a GeneratorExit error. | |
zctPlanes.next() | |
except StopIteration: | |
pass | |
for theC, mm in enumerate(channelsMinMax): | |
pixelsService.setChannelGlobalMinMax(pixelsId, theC, float(mm[0]), float(mm[1]), self.SERVICE_OPTS) | |
#resetRenderingSettings(renderingEngine, pixelsId, theC, mm[0], mm[1]) | |
# put the image in dataset, if specified. | |
if dataset: | |
link = omero.model.DatasetImageLinkI() | |
link.parent = omero.model.DatasetI(dataset.getId(), False) | |
link.child = omero.model.ImageI(image.id.val, False) | |
updateService.saveObject(link, self.SERVICE_OPTS) | |
return ImageWrapper(self, image) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment