large-image-source-tifffile 1.28.3.dev2__py3-none-any.whl → 1.30.7.dev10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- large_image_source_tifffile/__init__.py +122 -12
- {large_image_source_tifffile-1.28.3.dev2.dist-info → large_image_source_tifffile-1.30.7.dev10.dist-info}/METADATA +18 -4
- large_image_source_tifffile-1.30.7.dev10.dist-info/RECORD +8 -0
- {large_image_source_tifffile-1.28.3.dev2.dist-info → large_image_source_tifffile-1.30.7.dev10.dist-info}/WHEEL +1 -1
- large_image_source_tifffile-1.28.3.dev2.dist-info/RECORD +0 -8
- {large_image_source_tifffile-1.28.3.dev2.dist-info → large_image_source_tifffile-1.30.7.dev10.dist-info}/LICENSE +0 -0
- {large_image_source_tifffile-1.28.3.dev2.dist-info → large_image_source_tifffile-1.30.7.dev10.dist-info}/entry_points.txt +0 -0
- {large_image_source_tifffile-1.28.3.dev2.dist-info → large_image_source_tifffile-1.30.7.dev10.dist-info}/top_level.txt +0 -0
@@ -7,7 +7,6 @@ from importlib.metadata import PackageNotFoundError
|
|
7
7
|
from importlib.metadata import version as _importlib_version
|
8
8
|
|
9
9
|
import numpy as np
|
10
|
-
import zarr
|
11
10
|
|
12
11
|
import large_image
|
13
12
|
from large_image.cache_util import LruCacheMetaclass, methodcache
|
@@ -16,6 +15,7 @@ from large_image.exceptions import TileSourceError, TileSourceFileNotFoundError
|
|
16
15
|
from large_image.tilesource import FileTileSource
|
17
16
|
|
18
17
|
tifffile = None
|
18
|
+
zarr = None
|
19
19
|
|
20
20
|
try:
|
21
21
|
__version__ = _importlib_version(__name__)
|
@@ -37,6 +37,7 @@ def _lazyImport():
|
|
37
37
|
module initialization because it is slow.
|
38
38
|
"""
|
39
39
|
global tifffile
|
40
|
+
global zarr
|
40
41
|
|
41
42
|
if tifffile is None:
|
42
43
|
try:
|
@@ -55,6 +56,8 @@ def _lazyImport():
|
|
55
56
|
logging.getLogger('tifffile.tifffile').addHandler(checkForMissingDataHandler())
|
56
57
|
logging.getLogger('tifffile').setLevel(logging.WARNING)
|
57
58
|
logging.getLogger('tifffile').addHandler(checkForMissingDataHandler())
|
59
|
+
if zarr is None:
|
60
|
+
import zarr
|
58
61
|
|
59
62
|
|
60
63
|
def et_findall(tag, text):
|
@@ -180,7 +183,7 @@ class TifffileFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
|
|
180
183
|
ex = 'no maximum series'
|
181
184
|
try:
|
182
185
|
for idx, s in enumerate(self._tf.series):
|
183
|
-
samples =
|
186
|
+
samples = math.prod(s.shape)
|
184
187
|
if samples > maxsamples and 'X' in s.axes and 'Y' in s.axes:
|
185
188
|
maxseries = idx
|
186
189
|
maxsamples = samples
|
@@ -229,7 +232,7 @@ class TifffileFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
|
|
229
232
|
'sizeX': s.shape[s.axes.index('X')], 'sizeY': s.shape[s.axes.index('Y')]})
|
230
233
|
self.sizeX = max(self.sizeX, s.shape[s.axes.index('X')])
|
231
234
|
self.sizeY = max(self.sizeY, s.shape[s.axes.index('Y')])
|
232
|
-
self._framecount = len(self._series) *
|
235
|
+
self._framecount = len(self._series) * math.prod(tuple(
|
233
236
|
1 if base.axes[sidx] in 'YXS' else v for sidx, v in enumerate(base.shape)))
|
234
237
|
self._basis = {}
|
235
238
|
basis = 1
|
@@ -256,14 +259,17 @@ class TifffileFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
|
|
256
259
|
for p in self._tf.pages:
|
257
260
|
if (p not in pagesInSeries and getattr(p, 'keyframe', None) is not None and
|
258
261
|
p.hash not in hashes and not len(set(p.axes) - set('YXS'))):
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
262
|
+
try:
|
263
|
+
id = 'image_%s' % p.index
|
264
|
+
entry = {'page': p.index}
|
265
|
+
entry['width'] = p.shape[p.axes.index('X')]
|
266
|
+
entry['height'] = p.shape[p.axes.index('Y')]
|
267
|
+
if (id not in self._associatedImages and
|
268
|
+
max(entry['width'], entry['height']) <= self._maxAssociatedImageSize and
|
269
|
+
max(entry['width'], entry['height']) >= self._minAssociatedImageSize):
|
270
|
+
self._associatedImages[id] = entry
|
271
|
+
except Exception:
|
272
|
+
pass
|
267
273
|
for sidx, s in enumerate(self._tf.series):
|
268
274
|
if sidx not in self._series and not len(set(s.axes) - set('YXS')):
|
269
275
|
id = 'series_%d' % sidx
|
@@ -286,6 +292,79 @@ class TifffileFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
|
|
286
292
|
except Exception:
|
287
293
|
pass
|
288
294
|
|
295
|
+
def _handle_indica(self):
|
296
|
+
import xml.etree.ElementTree
|
297
|
+
|
298
|
+
import large_image.tilesource.utilities
|
299
|
+
|
300
|
+
try:
|
301
|
+
root = xml.etree.ElementTree.fromstring(self._tf.pages[0].description)
|
302
|
+
self._xml = large_image.tilesource.utilities.etreeToDict(root)
|
303
|
+
self._channels = [c['name'] for c in
|
304
|
+
self._xml['indica']['image']['channels']['channel']]
|
305
|
+
if len(self._basis) == 1 and 'I' in self._basis:
|
306
|
+
self._basis['C'] = self._basis.pop('I')
|
307
|
+
self._associatedImages.clear()
|
308
|
+
except Exception:
|
309
|
+
pass
|
310
|
+
|
311
|
+
def _handle_ome(self):
|
312
|
+
"""
|
313
|
+
For OME Tiff, if we didn't parse the mangification elsewhere, try to
|
314
|
+
parse it here.
|
315
|
+
"""
|
316
|
+
import xml.etree.ElementTree
|
317
|
+
|
318
|
+
import large_image.tilesource.utilities
|
319
|
+
|
320
|
+
_omeUnitsToMeters = {
|
321
|
+
'Ym': 1e24,
|
322
|
+
'Zm': 1e21,
|
323
|
+
'Em': 1e18,
|
324
|
+
'Pm': 1e15,
|
325
|
+
'Tm': 1e12,
|
326
|
+
'Gm': 1e9,
|
327
|
+
'Mm': 1e6,
|
328
|
+
'km': 1e3,
|
329
|
+
'hm': 1e2,
|
330
|
+
'dam': 1e1,
|
331
|
+
'm': 1,
|
332
|
+
'dm': 1e-1,
|
333
|
+
'cm': 1e-2,
|
334
|
+
'mm': 1e-3,
|
335
|
+
'\u00b5m': 1e-6,
|
336
|
+
'nm': 1e-9,
|
337
|
+
'pm': 1e-12,
|
338
|
+
'fm': 1e-15,
|
339
|
+
'am': 1e-18,
|
340
|
+
'zm': 1e-21,
|
341
|
+
'ym': 1e-24,
|
342
|
+
'\u00c5': 1e-10,
|
343
|
+
}
|
344
|
+
|
345
|
+
try:
|
346
|
+
root = xml.etree.ElementTree.fromstring(self._tf.pages[0].description)
|
347
|
+
self._xml = large_image.tilesource.utilities.etreeToDict(root)
|
348
|
+
except Exception:
|
349
|
+
return
|
350
|
+
try:
|
351
|
+
try:
|
352
|
+
base = self._xml['OME']['Image'][0]['Pixels']
|
353
|
+
except Exception:
|
354
|
+
base = self._xml['OME']['Image']['Pixels']
|
355
|
+
if self._mm_x is None and 'PhysicalSizeX' in base:
|
356
|
+
self._mm_x = (
|
357
|
+
float(base['PhysicalSizeX']) * 1e3 *
|
358
|
+
_omeUnitsToMeters[base.get('PhysicalSizeXUnit', '\u00b5m')])
|
359
|
+
if self._mm_y is None and 'PhysicalSizeY' in base:
|
360
|
+
self._mm_y = (
|
361
|
+
float(base['PhysicalSizeY']) * 1e3 *
|
362
|
+
_omeUnitsToMeters[base.get('PhysicalSizeYUnit', '\u00b5m')])
|
363
|
+
self._mm_x = self._mm_x or self._mm_y
|
364
|
+
self._mm_y = self._mm_y or self._mm_x
|
365
|
+
except Exception:
|
366
|
+
pass
|
367
|
+
|
289
368
|
def _handle_scn(self): # noqa
|
290
369
|
"""
|
291
370
|
For SCN files, parse the xml and possibly adjust how associated images
|
@@ -351,6 +430,20 @@ class TifffileFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
|
|
351
430
|
except Exception:
|
352
431
|
pass
|
353
432
|
|
433
|
+
def _handle_internal_ndpi(self, intmeta):
|
434
|
+
try:
|
435
|
+
ndpi = intmeta.pop('65449')
|
436
|
+
intmeta['ndpi'] = {}
|
437
|
+
for line in ndpi.replace('\r', '\n').split('\n'):
|
438
|
+
if '=' in line:
|
439
|
+
key, value = line.split('=', 1)
|
440
|
+
key = key.strip()
|
441
|
+
value = value.strip()
|
442
|
+
if key and key not in intmeta['ndpi'] and value:
|
443
|
+
intmeta['ndpi'][key] = value
|
444
|
+
except Exception:
|
445
|
+
pass
|
446
|
+
|
354
447
|
def getNativeMagnification(self):
|
355
448
|
"""
|
356
449
|
Get the magnification at a particular level.
|
@@ -420,6 +513,10 @@ class TifffileFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
|
|
420
513
|
json.dumps(result[key][subkey])
|
421
514
|
except Exception:
|
422
515
|
del result[key][subkey]
|
516
|
+
for key in dir(self._tf):
|
517
|
+
if (key.startswith('is_') and hasattr(self, '_handle_internal_' + key[3:]) and
|
518
|
+
getattr(self._tf, key)):
|
519
|
+
getattr(self, '_handle_internal_' + key[3:])(result)
|
423
520
|
if hasattr(self, '_xml') and 'xml' not in result:
|
424
521
|
result.pop('ImageDescription', None)
|
425
522
|
result['xml'] = self._xml
|
@@ -490,6 +587,17 @@ class TifffileFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
|
|
490
587
|
self._nonempty_levels_list[frame] = nonempty
|
491
588
|
return nonempty
|
492
589
|
|
590
|
+
def getPreferredLevel(self, level):
|
591
|
+
"""
|
592
|
+
Given a desired level (0 is minimum resolution, self.levels - 1 is max
|
593
|
+
resolution), return the level that contains actual data that is no
|
594
|
+
lower resolution.
|
595
|
+
|
596
|
+
:param level: desired level
|
597
|
+
:returns level: a level with actual data that is no lower resolution.
|
598
|
+
"""
|
599
|
+
return max(0, min(level, self.levels - 1))
|
600
|
+
|
493
601
|
def _getZarrArray(self, series, sidx):
|
494
602
|
with self._zarrlock:
|
495
603
|
if sidx not in self._zarrcache:
|
@@ -533,7 +641,7 @@ class TifffileFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
|
|
533
641
|
else:
|
534
642
|
bza = za
|
535
643
|
if step > 2 ** self._maxSkippedLevels:
|
536
|
-
tile = self._getTileFromEmptyLevel(x, y, z, **kwargs)
|
644
|
+
tile, _format = self._getTileFromEmptyLevel(x, y, z, **kwargs)
|
537
645
|
tile = large_image.tilesource.base._imageToNumpy(tile)[0]
|
538
646
|
else:
|
539
647
|
sel = []
|
@@ -549,6 +657,8 @@ class TifffileFileTileSource(FileTileSource, metaclass=LruCacheMetaclass):
|
|
549
657
|
sel.append(slice(series.shape[aidx]))
|
550
658
|
baxis += 'S'
|
551
659
|
else:
|
660
|
+
if axis not in self._basis and axis == 'I':
|
661
|
+
axis = 'C'
|
552
662
|
sel.append((frame // self._basis[axis][0]) % self._basis[axis][2])
|
553
663
|
tile = bza[tuple(sel)]
|
554
664
|
# rotate
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: large-image-source-tifffile
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.30.7.dev10
|
4
4
|
Summary: A tifffile tilesource for large_image.
|
5
5
|
Home-page: https://github.com/girder/large_image
|
6
6
|
Author: Kitware, Inc.
|
@@ -15,14 +15,28 @@ Classifier: Programming Language :: Python :: 3.9
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.10
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
18
19
|
Requires-Python: >=3.8
|
20
|
+
Description-Content-Type: text/x-rst
|
19
21
|
License-File: LICENSE
|
20
|
-
Requires-Dist: large-image
|
22
|
+
Requires-Dist: large-image>=1.30.7.dev10
|
21
23
|
Requires-Dist: dask[array]
|
22
24
|
Requires-Dist: tifffile[all]
|
23
25
|
Requires-Dist: zarr
|
24
26
|
Provides-Extra: girder
|
25
|
-
Requires-Dist: girder-large-image
|
27
|
+
Requires-Dist: girder-large-image>=1.30.7.dev10; extra == "girder"
|
28
|
+
Dynamic: author
|
29
|
+
Dynamic: author-email
|
30
|
+
Dynamic: classifier
|
31
|
+
Dynamic: description
|
32
|
+
Dynamic: description-content-type
|
33
|
+
Dynamic: home-page
|
34
|
+
Dynamic: keywords
|
35
|
+
Dynamic: license
|
36
|
+
Dynamic: provides-extra
|
37
|
+
Dynamic: requires-dist
|
38
|
+
Dynamic: requires-python
|
39
|
+
Dynamic: summary
|
26
40
|
|
27
41
|
A tifffile tilesource for large_image.
|
28
42
|
|
@@ -0,0 +1,8 @@
|
|
1
|
+
large_image_source_tifffile/__init__.py,sha256=vU1bFrCyklocQjzwiwiAITwLm0sfk-TnyDlIAwxqFeA,28899
|
2
|
+
large_image_source_tifffile/girder_source.py,sha256=8YsxpSK_UzbAcpjn6fIMlgKye2FchkB8_HTSQV0FpRA,1064
|
3
|
+
large_image_source_tifffile-1.30.7.dev10.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
4
|
+
large_image_source_tifffile-1.30.7.dev10.dist-info/METADATA,sha256=ESkktkSCBeCvqOXMH5oFMgUnce9s94mAc3CkHO2o-V4,1405
|
5
|
+
large_image_source_tifffile-1.30.7.dev10.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
6
|
+
large_image_source_tifffile-1.30.7.dev10.dist-info/entry_points.txt,sha256=aILCN5f7-Zj8-WRXcABxCQvqJv9VLTvqRhZ_7HEyokc,190
|
7
|
+
large_image_source_tifffile-1.30.7.dev10.dist-info/top_level.txt,sha256=feOAsix2Rzy6mjy2Ua-N0-L6tlKsgvLdRhO6Hd8_ZFs,28
|
8
|
+
large_image_source_tifffile-1.30.7.dev10.dist-info/RECORD,,
|
@@ -1,8 +0,0 @@
|
|
1
|
-
large_image_source_tifffile/__init__.py,sha256=7hREWGbhyYOcz94l_vxMAOTUSJKtJY37TEIZdkvamNw,25001
|
2
|
-
large_image_source_tifffile/girder_source.py,sha256=8YsxpSK_UzbAcpjn6fIMlgKye2FchkB8_HTSQV0FpRA,1064
|
3
|
-
large_image_source_tifffile-1.28.3.dev2.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
4
|
-
large_image_source_tifffile-1.28.3.dev2.dist-info/METADATA,sha256=2XRfComEY1H1fO7m6luWIfzukgRCnPmPJw6RVkiDpZw,1061
|
5
|
-
large_image_source_tifffile-1.28.3.dev2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
-
large_image_source_tifffile-1.28.3.dev2.dist-info/entry_points.txt,sha256=aILCN5f7-Zj8-WRXcABxCQvqJv9VLTvqRhZ_7HEyokc,190
|
7
|
-
large_image_source_tifffile-1.28.3.dev2.dist-info/top_level.txt,sha256=feOAsix2Rzy6mjy2Ua-N0-L6tlKsgvLdRhO6Hd8_ZFs,28
|
8
|
-
large_image_source_tifffile-1.28.3.dev2.dist-info/RECORD,,
|
File without changes
|
File without changes
|