diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f61c0684..9026fb35d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,11 @@ - Improve uint16 image scaling ([#1511](../../pull/1511)) - Read some untiled tiffs using the tiff source ([#1512](../../pull/1512)) - Speed up multi source compositing in tiled cases ([#1513](../../pull/1513)) +- Speed up some tifffile and multi source access cases ([#1515](../../pull/1515)) ### Changes - Limit internal metadata on multi-source files with huge numbers of sources ([#1514](../../pull/1514)) +- Make DICOMweb assetstore imports compatible with Girder generics ([#1504](../../pull/1504)) ## 1.28.1 diff --git a/sources/multi/large_image_source_multi/__init__.py b/sources/multi/large_image_source_multi/__init__.py index 5a8f094ed..bf5d899f4 100644 --- a/sources/multi/large_image_source_multi/__init__.py +++ b/sources/multi/large_image_source_multi/__init__.py @@ -828,7 +828,8 @@ def _openSource(self, source, params=None): with self._lastOpenSourceLock: if (hasattr(self, '_lastOpenSource') and self._lastOpenSource['source'] == source and - self._lastOpenSource['params'] == params): + (self._lastOpenSource['params'] == params or ( + params == {} and self._lastOpenSource['params'] is None))): return self._lastOpenSource['ts'] if not len(large_image.tilesource.AvailableTileSources): large_image.tilesource.loadTileSources() @@ -841,6 +842,7 @@ def _openSource(self, source, params=None): if params is None: params = source.get('params', {}) ts = openFunc(source['path'], **params) + source['sourceName'] = ts.name with self._lastOpenSourceLock: self._lastOpenSource = { 'source': source, diff --git a/sources/tifffile/large_image_source_tifffile/__init__.py b/sources/tifffile/large_image_source_tifffile/__init__.py index e4d623109..613e7015e 100644 --- a/sources/tifffile/large_image_source_tifffile/__init__.py +++ b/sources/tifffile/large_image_source_tifffile/__init__.py @@ -474,19 +474,12 @@ def _nonemptyLevelsList(self, frame=0): sidx = frame // self._basis['P'][0] else: sidx = 0 - series = self._tf.series[self._series[sidx]] nonempty = [None] * self.levels nonempty[self.levels - 1] = True + series = self._tf.series[self._series[sidx]] + za, hasgbs = self._getZarrArray(series, sidx) xidx = series.axes.index('X') yidx = series.axes.index('Y') - with self._zarrlock: - if sidx not in self._zarrcache: - if len(self._zarrcache) > 10: - self._zarrcache = {} - za = zarr.open(series.aszarr(), mode='r') - hasgbs = hasattr(za[0], 'get_basic_selection') - self._zarrcache[sidx] = (za, hasgbs) - za, hasgbs = self._zarrcache[sidx] for ll in range(1, len(series.levels)): scale = round(math.log(max(za[0].shape[xidx] / za[ll].shape[xidx], za[0].shape[yidx] / za[ll].shape[yidx])) / math.log(2)) @@ -497,6 +490,19 @@ def _nonemptyLevelsList(self, frame=0): self._nonempty_levels_list[frame] = nonempty return nonempty + def _getZarrArray(self, series, sidx): + with self._zarrlock: + if sidx not in self._zarrcache: + if len(self._zarrcache) > 10: + self._zarrcache = {} + za = zarr.open(series.aszarr(), mode='r') + hasgbs = hasattr(za[0], 'get_basic_selection') + if not hasgbs and math.prod(series.shape) < 256 * 1024 ** 2: + za = series.asarray() + self._zarrcache[sidx] = (za, hasgbs) + za, hasgbs = self._zarrcache[sidx] + return za, hasgbs + @methodcache() def getTile(self, x, y, z, pilImageAllowed=False, numpyAllowed=False, **kwargs): frame = self._getFrame(**kwargs) @@ -507,14 +513,7 @@ def getTile(self, x, y, z, pilImageAllowed=False, numpyAllowed=False, **kwargs): else: sidx = 0 series = self._tf.series[self._series[sidx]] - with self._zarrlock: - if sidx not in self._zarrcache: - if len(self._zarrcache) > 10: - self._zarrcache = {} - za = zarr.open(series.aszarr(), mode='r') - hasgbs = hasattr(za[0], 'get_basic_selection') - self._zarrcache[sidx] = (za, hasgbs) - za, hasgbs = self._zarrcache[sidx] + za, hasgbs = self._getZarrArray(series, sidx) xidx = series.axes.index('X') yidx = series.axes.index('Y') if hasgbs: