Skip to content

Commit

Permalink
Speed up some tifffile and multi source access cases
Browse files Browse the repository at this point in the history
For small tifffile arrays, use them directly rather than with zarr
access.

Note which source was used to open a file in the multisource source so
if it needs to be reopened, we can do so more efficiently.
  • Loading branch information
manthey committed Apr 26, 2024
1 parent 3b59156 commit 2b0d08a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 18 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 3 additions & 1 deletion sources/multi/large_image_source_multi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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,
Expand Down
34 changes: 17 additions & 17 deletions sources/tifffile/large_image_source_tifffile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -497,6 +490,20 @@ 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 = {}
if math.prod(series.shape) < 256 * 1024 ** 2:
za = series.asarray()
else:
za = zarr.open(series.aszarr(), mode='r')
hasgbs = hasattr(za[0], 'get_basic_selection')
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)
Expand All @@ -507,14 +514,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:
Expand Down

0 comments on commit 2b0d08a

Please sign in to comment.