def _newAxes(self): """Given self._rotation and self._swapped, calculates and sets the appropriate data2scene transformation. """ # TODO: this function works, but it is not elegant. There must # be a simpler way to calculate the appropriate tranformation. w, h = self.dataShape assert self._rotation in range(0, 4) # unlike self._rotation, the local variable 'rotation' # indicates how many times to rotate clockwise after swapping # axes. # t1 : do axis swap t1 = QTransform() if self._swapped: t1 = QTransform(0, 1, 0, 1, 0, 0, 0, 0, 1) h, w = w, h # t2 : do rotation t2 = QTransform() t2.rotate(self._rotation * 90) # t3: shift to re-center rot2trans = {0: (0, 0), 1: (h, 0), 2: (w, h), 3: (0, w)} trans = rot2trans[self._rotation] t3 = QTransform.fromTranslate(*trans) self.data2scene = t1 * t2 * t3 if self._tileProvider: self._tileProvider.axesSwapped = self._swapped self.axesChanged.emit(self._rotation, self._swapped)
def _fetch_tile_layer(self, timestamp, ims, transform, tile_nr, stack_id, ims_req, cache): """ Fetch a single tile from a layer (ImageSource). Parameters ---------- timestamp The timestamp at which ims_req was created ims The layer (image source) we're fetching from transform The transform to apply to the fetched data, before storing it in the cache tile_nr The ID of the fetched tile stack_id The stack ID of the tile we're fetching (e.g. which T-slice and Z-slice this tile belongs to) ims_req A request object (e.g. GrayscaleImageRequest) with a wait() method that produces an item of the appropriate type for the layer (i.e. either a QImage or a QGraphicsItem) cache The value of self._cache at the time the ims_req was created. (The cache can be replaced occasionally. See TileProvider._onSizeChanged().) """ try: try: with cache: layerTimestamp = cache.layerTimestamp(stack_id, ims, tile_nr) except KeyError: # May not be a timestamp yet (especially when prefetching) layerTimestamp = 0 tile_rect = QRectF( self.tiling.imageRects[tile_nr] ) if timestamp > layerTimestamp: img = ims_req.wait() if isinstance(img, QImage): img = img.transformed(transform) elif isinstance(img, QGraphicsItem): # FIXME: It *seems* like applying the same transform to QImages and QGraphicsItems # makes sense here, but for some strange reason it isn't right. # For QGraphicsItems, it seems obvious that this is the correct transform. # I do not understand the formula that produces 'transform', which is used for QImage tiles. img.setTransform(QTransform.fromTranslate(tile_rect.left(), tile_rect.top()), combine=True) img.setTransform(self.tiling.data2scene, combine=True) else: assert False, "Unexpected image type: {}".format( type(img) ) with cache: try: cache.updateTileIfNecessary(stack_id, ims, tile_nr, timestamp, img) except KeyError: pass if stack_id == self._current_stack_id \ and cache is self._cache: self.sceneRectChanged.emit( tile_rect ) except BaseException: sys.excepthook( *sys.exc_info() )
def _newAxes(self): """Given self._rotation and self._swapped, calculates and sets the appropriate data2scene transformation. """ # TODO: this function works, but it is not elegant. There must # be a simpler way to calculate the appropriate transformation. w, h = self.dataShape assert self._rotation in range(0, 4) # unlike self._rotation, the local variable 'rotation' # indicates how many times to rotate clockwise after swapping # axes. # t1 : do axis swap t1 = QTransform() if self._swapped: t1 = QTransform(0, 1, 0, 1, 0, 0, 0, 0, 1) h, w = w, h # t2 : do rotation t2 = QTransform() t2.rotate(self._rotation * 90) # t3: shift to re-center rot2trans = {0 : (0, 0), 1 : (h, 0), 2 : (w, h), 3 : (0, w)} trans = rot2trans[self._rotation] t3 = QTransform.fromTranslate(*trans) self.data2scene = t1 * t2 * t3 if self._tileProvider: self._tileProvider.axesSwapped = self._swapped self.axesChanged.emit(self._rotation, self._swapped)