def execute(self, slot, subindex, roi, result): assert slot == self.Output, "Unknown slot: {}".format( slot.name ) radius = self.CrosshairRadius.value points = map(TinyVector, self.PointList.value) result[:] = 0 result_view = result.view(vigra.VigraArray) result_view.axistags = self.Output.meta.axistags result_3d = result_view.withAxes(*'xyz') axiskeys = self.Output.meta.getAxisKeys() roi_start_3d = TinyVector(roi.start) roi_stop_3d = TinyVector(roi.stop) try: roi_start_3d.pop( axiskeys.index('c') ) roi_stop_3d.pop( axiskeys.index('c') ) except ValueError: pass try: roi_start_3d.pop( axiskeys.index('t') ) roi_stop_3d.pop( axiskeys.index('t') ) except ValueError: pass for point3d in points: point3d -= roi_start_3d cross_min = point3d - radius cross_max = point3d + radius+1 # If the cross would be entirely out-of-view, skip it. if (cross_max < [0,0,0]).any() or \ (cross_min >= result_3d.shape).any(): continue cross_min = numpy.maximum(cross_min, (0,0,0)) cross_max = numpy.minimum(cross_max, result_3d.shape) x,y,z = point3d x1,y1,z1 = cross_min x2,y2,z2 = cross_max if 0 <= y < result_3d.shape[1] and 0 <= z < result_3d.shape[2]: result_3d[x1:x2, y, z ] = 1 if 0 <= x < result_3d.shape[0] and 0 <= z < result_3d.shape[2]: result_3d[x, y1:y2, z ] = 1 if 0 <= x < result_3d.shape[0] and 0 <= y < result_3d.shape[1]: result_3d[x, y, z1:z2] = 1 return result
def execute(self, slot, subindex, roi, result): assert slot == self.Output, "Unknown slot: {}".format(slot.name) radius = self.CrosshairRadius.value points = map(TinyVector, self.PointList.value) result[:] = 0 result_view = result.view(vigra.VigraArray) result_view.axistags = self.Output.meta.axistags result_3d = result_view.withAxes(*'xyz') axiskeys = self.Output.meta.getAxisKeys() roi_start_3d = TinyVector(roi.start) roi_stop_3d = TinyVector(roi.stop) try: roi_start_3d.pop(axiskeys.index('c')) roi_stop_3d.pop(axiskeys.index('c')) except ValueError: pass try: roi_start_3d.pop(axiskeys.index('t')) roi_stop_3d.pop(axiskeys.index('t')) except ValueError: pass for point3d in points: point3d -= roi_start_3d cross_min = point3d - radius cross_max = point3d + radius + 1 # If the cross would be entirely out-of-view, skip it. if (cross_max < [0,0,0]).any() or \ (cross_min >= result_3d.shape).any(): continue cross_min = numpy.maximum(cross_min, (0, 0, 0)) cross_max = numpy.minimum(cross_max, result_3d.shape) x, y, z = point3d x1, y1, z1 = cross_min x2, y2, z2 = cross_max if 0 <= y < result_3d.shape[1] and 0 <= z < result_3d.shape[2]: result_3d[x1:x2, y, z] = 1 if 0 <= x < result_3d.shape[0] and 0 <= z < result_3d.shape[2]: result_3d[x, y1:y2, z] = 1 if 0 <= x < result_3d.shape[0] and 0 <= y < result_3d.shape[1]: result_3d[x, y, z1:z2] = 1 return result
class SubRegion(Roi): def __init__(self, slot, start = None, stop = None, pslice = None): super(SubRegion,self).__init__(slot) shape = None if slot is not None: shape = slot.meta.shape if pslice != None or start is not None and stop is None and pslice is None: if pslice is None: pslice = start if shape is None: # Okay to use a shapeless slot if the key is bounded # AND if the key has the correct length assert slicingtools.is_bounded(pslice) # Supply a dummy shape shape = [0] * len(pslice) self.start, self.stop = sliceToRoi(pslice,shape) elif start is None and pslice is None: assert shape is not None, "Can't create a default subregion without a slot and a shape." self.start, self.stop = roiFromShape(shape) else: self.start = TinyVector(start) self.stop = TinyVector(stop) self.dim = len(self.start) for start, stop in zip(self.start, self.stop): assert isinstance(start, (int, long, numpy.integer)), "Roi contains non-integers: {}".format( self ) assert isinstance(start, (int, long, numpy.integer)), "Roi contains non-integers: {}".format( self ) # FIXME: This assertion is good at finding bugs, but it is currently triggered by # the DataExport applet when the output axis order is changed. # # if self.slot is not None self.slot.meta.shape is not None: # assert all(self.stop <= self.slot.meta.shape), \ # "Roi is out of bounds. roi={}, {}.{}.meta.shape={}"\ # .format((self.start, self.stop), slot.getRealOperator().name, slot.name, self.slot.meta.shape) def __setstate__(self, state): """ Support copy.copy() """ self.slot = state['slot'] self.start = TinyVector( state['start'] ) self.stop = TinyVector( state['stop'] ) self.dim = len( state['start'] ) def __str__( self ): return "".join(("Subregion: start '", str(self.start), "' stop '", str(self.stop), "'")) def pprint(self): """pretty-print this object""" ret = "" for a,b in zip(self.start, self.stop): ret += "%d-%d " % (a,b) return ret @staticmethod def _toString(roi): assert isinstance(roi, SubRegion) assert roi.slot is None, "Can't stringify SubRegions with no slot" return "SubRegion(None, {}, {})".format(roi.start, roi.stop) @staticmethod def _fromString(s): return eval(s) def setInputShape(self,inputShape): assert type(inputShape) == tuple self.inputShape = inputShape def copy(self): return copy.copy(self) def popDim(self, dim): """ remove the i'th dimension from the SubRegion works inplace ! """ if dim is not None: self.start.pop(dim) self.stop.pop(dim) return self def setDim(self, dim , start, stop): """ change the subarray at dim, to begin at start and to end at stop """ self.start[dim] = start self.stop[dim] = stop return self def insertDim(self, dim, start, stop): """ insert a new dimension before dim. set start to start, stop to stop and the axistags to at """ self.start = self.start.insert(dim,start) self.stop = self.stop.insert(dim,stop) return self def expandByShape(self,shape,cIndex,tIndex): """ extend a roi by a given in shape """ #TODO: Warn if bounds are exceeded cStart = self.start[cIndex] cStop = self.stop[cIndex] if tIndex is not None: tStart = self.start[tIndex] tStop = self.stop[tIndex] if isinstance(shape, collections.Iterable): #add a dummy number for the channel dimension shape = shape+(1,) else: tmp = shape shape = numpy.zeros(self.dim).astype(int) shape[:] = tmp tmpStart = [int(x-s) for x,s in zip(self.start,shape)] tmpStop = [int(x+s) for x,s in zip(self.stop,shape)] start = [int(max(t,i)) for t,i in zip(tmpStart,numpy.zeros_like(self.inputShape))] stop = [int(min(t,i)) for t,i in zip(tmpStop,self.inputShape)] start[cIndex] = cStart stop[cIndex] = cStop if tIndex is not None: start[tIndex] = tStart stop[tIndex] = tStop self.start = TinyVector(start) self.stop = TinyVector(stop) return self def adjustRoi(self,halo,cIndex=None): if type(halo) != list: halo = [halo]*len(self.start) notAtStartEgde = map(lambda x,y: True if x<y else False,halo,self.start) for i in range(len(notAtStartEgde)): if notAtStartEgde[i]: self.stop[i] = int(self.stop[i]-self.start[i]+halo[i]) self.start[i] = int(halo[i]) return self def adjustChannel(self,cPerC,cIndex,channelRes): if cPerC != 1 and channelRes == 1: start = [self.start[i]/cPerC if i == cIndex else self.start[i] for i in range(len(self.start))] stop = [self.stop[i]/cPerC+1 if i==cIndex else self.stop[i] for i in range(len(self.stop))] self.start = TinyVector(start) self.stop = TinyVector(stop) elif channelRes > 1: start = [0 if i == cIndex else self.start[i] for i in range(len(self.start))] stop = [channelRes if i==cIndex else self.stop[i] for i in range(len(self.stop))] self.start = TinyVector(start) self.stop = TinyVector(stop) return self def toSlice(self, hardBind = False): return roiToSlice(self.start,self.stop, hardBind)
class SubRegion(Roi): def __init__(self, slot, start=None, stop=None, pslice=None): super(SubRegion, self).__init__(slot) if pslice != None or start is not None and stop is None and pslice is None: if pslice is None: pslice = start shape = self.slot.meta.shape if shape is None: # Okay to use a shapeless slot if the key is bounded # AND if the key has the correct length assert slicingtools.is_bounded(pslice) # Supply a dummy shape shape = [0] * len(pslice) self.start, self.stop = sliceToRoi(pslice, shape) elif start is None and pslice is None: self.start, self.stop = sliceToRoi(slice(None, None, None), self.slot.meta.shape) else: self.start = TinyVector(start) self.stop = TinyVector(stop) self.dim = len(self.start) def __str__(self): return "".join(("Subregion: start '", str(self.start), "' stop '", str(self.stop), "'")) @staticmethod def _toString(roi): assert isinstance(roi, SubRegion) assert roi.slot is None, "Can't stringify SubRegions with no slot" return "SubRegion(None, {}, {})".format(roi.start, roi.stop) @staticmethod def _fromString(s): return eval(s) def setInputShape(self, inputShape): assert type(inputShape) == tuple self.inputShape = inputShape def copy(self): return copy.copy(self) def popDim(self, dim): """ remove the i'th dimension from the SubRegion works inplace ! """ if dim is not None: self.start.pop(dim) self.stop.pop(dim) return self def setDim(self, dim, start, stop): """ change the subarray at dim, to begin at start and to end at stop """ self.start[dim] = start self.stop[dim] = stop return self def insertDim(self, dim, start, stop, at): """ insert a new dimension before dim. set start to start, stop to stop and the axistags to at """ self.start.insert(0, start) self.stop.insert(0, stop) return self def expandByShape(self, shape, cIndex, tIndex): """ extend a roi by a given in shape """ # TODO: Warn if bounds are exceeded cStart = self.start[cIndex] cStop = self.stop[cIndex] if tIndex is not None: tStart = self.start[tIndex] tStop = self.stop[tIndex] if isinstance(shape, collections.Iterable): # add a dummy number for the channel dimension shape = shape + (1,) else: tmp = shape shape = numpy.zeros(self.dim).astype(int) shape[:] = tmp tmpStart = [int(x - s) for x, s in zip(self.start, shape)] tmpStop = [int(x + s) for x, s in zip(self.stop, shape)] start = [int(max(t, i)) for t, i in zip(tmpStart, numpy.zeros_like(self.inputShape))] stop = [int(min(t, i)) for t, i in zip(tmpStop, self.inputShape)] start[cIndex] = cStart stop[cIndex] = cStop if tIndex is not None: start[tIndex] = tStart stop[tIndex] = tStop self.start = TinyVector(start) self.stop = TinyVector(stop) return self def adjustRoi(self, halo, cIndex=None): if type(halo) != list: halo = [halo] * len(self.start) notAtStartEgde = map(lambda x, y: True if x < y else False, halo, self.start) for i in range(len(notAtStartEgde)): if notAtStartEgde[i]: self.stop[i] = int(self.stop[i] - self.start[i] + halo[i]) self.start[i] = int(halo[i]) return self def adjustChannel(self, cPerC, cIndex, channelRes): if cPerC != 1 and channelRes == 1: start = [self.start[i] / cPerC if i == cIndex else self.start[i] for i in range(len(self.start))] stop = [self.stop[i] / cPerC + 1 if i == cIndex else self.stop[i] for i in range(len(self.stop))] self.start = TinyVector(start) self.stop = TinyVector(stop) elif channelRes > 1: start = [0 if i == cIndex else self.start[i] for i in range(len(self.start))] stop = [channelRes if i == cIndex else self.stop[i] for i in range(len(self.stop))] self.start = TinyVector(start) self.stop = TinyVector(stop) return self def toSlice(self, hardBind=False): return roiToSlice(self.start, self.stop, hardBind)